#reactjs #jsx
#reactjs #jsx
Вопрос:
Я хочу получить данные с помощью fetch () и передать их по иерархии моих компонентов и использовать эти данные для установки начального состояния одного из моих компонентов
Я попытался установить исходное состояние с помощью реквизита и передать их вниз.
componentDidMount = () => {
getFileSystem().then(response => {
if (response.success) {
this.setState({
filesystem: response.filesystem,
projects: response.projects
})
}
}).catch(err => {
this.setState({
filesystem: {
name: '/',
type: 'directory',
children: [
{ name: 'error.txt', type: 'file', data: 'error' }
]
},
projects: []
})
})
}
class TerminalContainer extends Component {
constructor(props) {
super(props)
this.state = {
filesystem: props.filesystem,
terminal_data: [''],
current_dir_name: '/',
current_dir: props.filesystem,
full_path: ""
}
}
...
Но компонент вызывает функцию конструктора до того, как данные будут загружены в реквизит компонента. Это означает, что исходное состояние компонента установлено неправильно.
Мне нужен какой-то способ предотвратить визуализацию компонента до тех пор, пока все данные не будут готовы
Комментарии:
1. Мне нужен какой-то способ предотвратить компонент — нет никакого способа. Если вам нужно отложить инициализацию компонента, сделайте это в родительском компоненте.
2. в родительском компоненте вы можете написать эту строку
{this.state.filesystem amp;amp; <TerminalContainer filesystem={this.state.filesystem} />
, чтобы предотвратить инициализациюTerminalContainer
, когда filesytem не определен
Ответ №1:
Если вы хотите использовать реквизит, предоставленный компоненту, в качестве начального состояния, и эти реквизиты являются состоянием в родительском компоненте, которые извлекаются асинхронно, вам необходимо отложить рендеринг дочернего компонента.
Вы могли бы, например, добавить дополнительную вызываемую часть состояния isLoading
, которую вы устанавливаете false
, когда выборка завершена, и использовать ее для условного отображения TerminalContainer
компонента.
Пример
class App extends React.Component {
state = {
isLoading: true,
filesystem: null,
projects: null
};
componentDidMount() {
getFileSystem()
.then(response => {
if (response.success) {
this.setState({
isLoading: false,
filesystem: response.filesystem,
projects: response.projects
});
}
})
.catch(err => {
this.setState({
isLoading: false,
filesystem: {
name: "/",
type: "directory",
children: [{ name: "error.txt", type: "file", data: "error" }]
},
projects: []
});
});
}
render() {
const { isLoading, filesystem } = this.state;
if (isLoading) {
return null;
}
return <TerminalContainer filesystem={filesystem} />;
}
}