Как установить исходное состояние из реквизита после выборки?

#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} />;
  }
}