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

Accessing Props after render in multi level component tree - React

我对 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 传递到组件中。

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

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

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

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

也许我只是愚蠢?

使用componentWillReceiveProps生命周期。

当您在 componentDidMount 的父组件中设置状态时,它 re-render 子组件,孙组件。

componentWillReceiveProps(nextProps) {

        if(nextProps.entities){

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

componentWillMount 仅在初始渲染时调用,而不是针对每个 re-rendering.In 你的情况,你需要处理 re-rendering 。

您正在使用响应设置状态。您 may/should 使用 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))
}

希望这对您有所帮助。

我觉得你的代码不错。我看到的唯一问题是您将道具显式传递给子组件而不检查它。在获取数据时 - 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>)

希望它有意义。

network requestasync 所以 network request 里面的 setState 不会在组件挂载时被调用。所以最初 this.state.entities 将等于 []。所以 [].id ie:(entities.id) 返回 undefined.

最初将 entities 设置为 null

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

并以

访问entities.id

entities ? entities.id : somethingElse