在多级组件树中渲染后访问道具 - React

时间:2018-03-23 15:11:58

标签: reactjs state react-props

我对React有些新意,我遇到了一个问题,我在组件,子组件和孙子中获得了未定义的道具。

这就是我的目标...

app.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传递给Component。

然后我需要在Component渲染之前访问props,所以我在componentWillMount()中执行此操作,然后将Component状态设置为作为props传递给ChildComponent?

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

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

最后,我的问题出现在我的ChildComponent或GrandChildComponent中,所有内容都在之前呈现并且道具或状态被设置。所以当我调用{entities.id}时,我得到一个未定义的。

也许我只是愚蠢?

4 个答案:

答案 0 :(得分:1)

使用componentWillReceiveProps生命周期。

componentDidMount中的父组件中设置状态时,它会重新呈现子孙组件。

componentWillReceiveProps(nextProps) {

        if(nextProps.entities){

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

componentWillMount仅在初始渲染时调用,而不是每次重新渲染。在您的情况下,您需要处理重新渲染。

答案 1 :(得分:1)

您的代码对我来说很好。我看到的唯一问题是你将props明确地传递给Child组件而不检查它。当您获取数据时 - 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>)

希望它有意义。

答案 2 :(得分:0)

您正在使用响应设置状态。您可以/应该使用来自API侧的数据设置状态。

componentWillMount()中,您必须获取数据并使用data参数设置状态,而不是润湿响应。

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))
}

希望,这可能会对你有帮助。

答案 3 :(得分:0)

network requestasync,因此在安装组件时,setState内的network request将不会被调用。所以最初this.state.entities将等于[]。所以[].id即:(entities.id)正在重新推出undefined

最初将entities设为null

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

并访问entities.id

entities ? entities.id : somethingElse