обновить состояние дочернего компонента react, используя реквизиты, полученные от асинхронного вызова API, выполненного в родительском компоненте

#reactjs #state #lifecycle #react-props

#reactjs #состояние #жизненный цикл #react-props

Вопрос:

что я хочу сделать, так это установить свое состояние с помощью реквизитов, но проблема в том, что мои реквизиты поступают из вызова API, выполненного в родительском компоненте (я использую react router dom). Итак, сначала я попытался использовать componentDidMount, который работает, когда вы переходите на главную (дочернюю) страницу со страницы приветствия (дочерняя), но когда вы напрямую переходите на домашнюю страницу, компонент mount заполняет состояние до выполнения вызова api (в основном, не определено).

затем я попытался использовать componentDidUpdate, который работает, когда вы переходите непосредственно к домашней (дочерней) странице, но componentDidUpdate даже не запускается при переходе со страницы приветствия (дочерней) на домашнюю (дочернюю).(опять не определено) (componentdidupdate не запускается при инициализации компонента, т. Е. При первом создании компонента) также, если вы перейдете на другой маршрут и вернетесь, он не работает в случае componentDidUpdate я думаю, что жизненный цикл компонента начинается с самого начала, может кто-нибудь подтвердить это, пожалуйста?

Теперь я использую как componentDidUpdate, так и componentDidMount в своем коде, и это работает хорошо. Я просто хочу знать, это лучший способ или есть другой способ заполнить состояние, используя реквизиты из вызова api

Домашний компонент

 constructor(props: HomeProps) {
    super(props);
    this.state = {
      myUser: {},
    }
  }


  componentDidUpdate = (prevProps: HomeProps) => {
    if (prevProps.userProfile.ID !== this.props.userProfile.ID) {
      this.setState({ myUser: this.props.userProfile });
    }
  }

componentDidMount = () => {
    this.setState({ myUser: this.props.userProfile })
  }
  

основной компонент (родительский)
добро пожаловать: path=»/»
Home: path=»/Home»

 <HashRouter>
<Switch>
    <Route exact path="/" render={(props) => (<Welcome {...props} />)} />
                   <Route exact path="/Home" render={(props) => (<Home authContext={this.props.authContext} {...props} userProfile={this.state.currentUser} />)} />
</Switch>
</HashRouter>
  

просто хочу знать правильный способ, и я также буду признателен, если вы сможете объяснить, почему это лучше.

Комментарии:

1. Home не является дочерним элементом Welcome. Они оба находятся на одном уровне, и только один из них будет отображаться из-за переключения.

2. да, это так, я обновил вопрос и изменил посадку на приветствие

Ответ №1:

Я бы структурировал это так, чтобы вместо того, чтобы использовать разные маршруты как родительский потомок, я бы рассматривал их как параллельные или родственные. И в этом сценарии я бы использовал Redux или предпочитаемое вами управление состоянием. По мере роста вашего приложения и добавления новых маршрутов вам придется передавать пользовательский реквизит из вашего родительского маршрута на все будущие маршруты, и это будет все большей проблемой для обслуживания.

При использовании инструмента управления состоянием, такого как Redux, все компоненты будут иметь доступ к состоянию, не нужно передавать реквизиты каждому компоненту, независимо от того, насколько глубоко проходит маршрут или сколько родственных маршрутов вы добавляете.

Ответ №2:

сначала вы должны использовать вызов API async / await, и вы можете использовать, как показано ниже, если вы используете async / await в самом api, чтобы решить эту проблему.

    constructor(props: HomeProps) {
        super(props);
        this.state = {
          myUser: {},
        }
      }        
      componentDidUpdate = async(prevProps: HomeProps) => {
        if (prevProps.userProfile.ID !== this.props.userProfile.ID) {
        await  this.setState({ myUser: this.props.userProfile });
        }
      }        
   componentDidMount = async () => {
       await this.setState({ myUser: this.props.userProfile })
      }