Доступ к реквизитам после рендеринга в многоуровневом дереве компонентов - React

Я новичок в React и сталкиваюсь с проблемой, когда я получаю неопределенные реквизиты в компонентах, дочерних компонентах и ​​внуках.

Вот что у меня происходит...

приложение.jsx

constructor(props) {
  super(props);
  this.state = {
    entities: [],
  }
}

componentDidMount() {
  axios.get(`api.com`)
  .then(response => {this.setState({entities: response,})});
}

render() {
  return (
    <div>
      <Component entities={this.state.entities} />
    </div>
  );
}

Насколько я понимаю, после монтирования компонента он выполняет вызов axios и устанавливает состояние. Затем я передаю state.entities в компонент.

Затем мне нужно получить доступ к реквизитам до рендеринга компонента, поэтому я делаю это в componentWillMount(), а затем устанавливаю состояние компонента для передачи в качестве реквизита дочернему компоненту?

componentWillMount() {
    var getEntities = this.props.entities
    this.setState({entities:getEntities})
  }

render() {
  return (
    <div>
      <ChildComponent entities={this.state.entities} />
    </div>
  );
}

В конце концов, моя проблема заключается в моем ChildComponent или GrandChildComponent, все рендерится до того, как устанавливаются реквизиты или состояние. Поэтому, когда я вызываю {entities.id}, я получаю неопределенное значение.

Может я просто тупой?


person jobiin    schedule 23.03.2018    source источник
comment
Является ли сущность объектом или массивом?   -  person Antonis Zisis    schedule 23.03.2018


Ответы (4)


Используйте жизненный цикл componentWillReceiveProps.

Когда вы устанавливаете состояние в родительском компоненте в componentDidMount, он повторно отображает дочерний элемент. ,внучатый компонент.

componentWillReceiveProps(nextProps) {

        if(nextProps.entities){

           this.setState({entities:nextProps.entities})
        }
    }

componentWillMount вызывается только при первоначальном рендеринге, а не при каждом повторном рендеринге. В вашем случае вам нужно выполнить повторный рендеринг.

person RIYAJ KHAN    schedule 23.03.2018

Ваш код выглядит хорошо для меня. Единственная проблема, которую я вижу, - это то, что вы явно передаете реквизиты в дочерний компонент, не проверяя его. Пока вы извлекаете данные - states равно [], и вы передаете его в дочерний компонент. Я бы добавил логическое состояние, например isFetched, и когда ваш запрос будет выполнен, установите для него значение true. Пока данные извлекаются, вы можете показывать loading. Пример ниже.

state = {
  entities: [],
  isFetched: false
}
...
componentDidMount() {
  axios.get(`api.com`)
   .then(response => {this.setState({entities: response, isFetched: true})});
}
...
render(){
  const {isFetched, entities} = this.state
  return (
    <div>{isFetched ? <ChildComponent {entities}> : 'Loading...'}</div>
  )
}

const ChildComponent = ({entities}) => (<div>{JSON.stringify(entities)}</div>)

Надеюсь, это имеет смысл.

person The Reason    schedule 23.03.2018

Вы устанавливаете состояние с ответом. Вы можете/должны установить состояние с данными со стороны API.

В componentWillMount() вы должны получить данные и установить состояние с параметром данных, а не мочить ответ.

componentWillMount() {
  axios.get(`api.com`)
  .then(response => response.json())
  .then((data) => this.setState({entities: data}))
}

Вы всегда можете выполнить console.log() перед установкой состояния.

componentWillMount() {
  axios.get(`api.com`)
  .then(response => response.json())
  .then((data) => console.log('this is entities data', data))
}

Надеюсь, это может вам помочь.

person Thananjaya S    schedule 23.03.2018

network request равно async, поэтому setState внутри network request не будет вызываться при монтировании компонента. поэтому изначально this.state.entities будет равно []. поэтому [].id ie:(entities.id) возвращает undefined.

изначально установить entities как null

constructor(props) {
  super(props);
  this.state = {
    entities: null;,
  }
}

и получить доступ к entities.id как

entities ? entities.id : somethingElse

person ramki    schedule 23.03.2018