Реагировать на проверку API-запроса перед передачей реквизита детям

У меня есть компонент Parent и компонент Child, и у меня есть действие, которое запускает некоторый вызов API в дочернем компоненте, а в componentWillMount я проверяю условие if на некоторые props, которые исходят от родителя, и выполняю некоторый триггер. Если условие истинно, я запускаю метод, который отображает новый компонент. Проблема в том, что в дочернем компоненте в componentWillmount props this.props.person и this.props.notFound не определены, но мне нужно дождаться запроса API перед рендерингом и проверить этот реквизит.

родитель:

export class Parent extends Component {

  state = {
    id: this.props.id || ''
  }

    render() {
        <Child value={this.state.value} onNotValidId={() => this.renderNewComponent()} />
    }

}

export const mapStateToProps = state => ({
    tagStatus: state.tagAssignment.status,
    persons: state.entities.persons,
)}

Дети:

export class Child extends Component {
  componentWillMount = () => {
         this.props.init(parseInt(this.props.id, 16), this.props.accessToken)
        if (!this.props.notFound && !this.props.person)
            this.props.onNotValidId()

    }

   render = () => {
      return (
         <div>Some body</div>
       )
   }
}

export const mapStateToProps = state => ({
    status: state.tagAssignment.status,
    person: state.entities.persons[state.tagAssignment.assignee],
    accessToken: state.auth.accessToken,
})

export const mapDispatchToProps = dispatch => ({
    init: (id, accessToken) => dispatch(checkId(id, accessToken)),
})

export default compose(
    connect(mapStateToProps, mapDispatchToProps),
)(Child)

person Palaniichuk Dmytro    schedule 11.05.2018    source источник
comment
Я бы, вероятно, использовал componentDidUpdate и установил состояние переменной, а затем использовал бы это, чтобы отображать дочерний элемент только при обновлении (например, в результате вызова API) и устанавливает смещение обновления.   -  person Afshin Ghazi    schedule 11.05.2018


Ответы (1)


Проблема, с которой вы столкнулись, возникает из-за того, что ваш вызов API происходит асинхронно с методами жизненного цикла реакции. К моменту возврата ответа API метод рендеринга родительского компонента был вызван в первый раз, что отобразило дочерний компонент, который, в свою очередь, вызвал компонент, который будет монтироваться с реквизитами, переданными ему родителем, до того, как они были инициализированы ответом API. данные. Когда результаты API, наконец, возвращаются и передаются в качестве новых реквизитов дочернему компоненту (результат повторного рендеринга родителей), он не запускает жизненный цикл componentWillMount, поскольку он уже смонтирован.

Вы можете решить эту проблему несколькими способами, и это действительно зависит от того, как вы планируете использовать дочерний компонент в будущем. Несколько решений:

1) В методе рендеринга родительских компонентов убедитесь, что дочерний компонент не отображается до тех пор, пока не будет возвращен ответ от API. Это гарантирует, что когда дочерний компонент монтируется в первый раз, у него будут действительные реквизиты для работы. например:

render() {
  this.state.value && <Child value={this.state.value} onNotValidId={() => this.renderNewComponent()} />
}

2) Переместите или продублируйте (в зависимости от того, как вы планируете использовать дочерний компонент) логику инициализации дочерних компонентов из/в другой хук жизненного цикла, такой как componentDidUpdate или getDerivedStateFromProps (в зависимости от версии React, которую вы поете)

person Tal Goldfus    schedule 11.05.2018