【问题标题】:Accessing Props after render in multi level component tree - React在多级组件树中渲染后访问道具 - React
【发布时间】:2018-09-02 07:43:08
【问题描述】:

我对 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} 我得到一个未定义的。

也许我只是个笨蛋?

【问题讨论】:

  • “实体”是对象还是数组?

标签: reactjs state react-props


【解决方案1】:

使用componentWillReceiveProps 生命周期。

当您在componentDidMount 的父组件中设置状态时,它会重新渲染子、孙子组件。

componentWillReceiveProps(nextProps) {

        if(nextProps.entities){

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

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

【讨论】:

    【解决方案2】:

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

    希望它有意义。

    【讨论】:

      【解决方案3】:

      您正在使用响应设置状态。您可以/应该使用来自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))
      }
      

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        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

        【讨论】:

          猜你喜欢
          • 2019-04-19
          • 2020-12-24
          • 1970-01-01
          • 2019-04-01
          • 2020-01-15
          • 2017-06-02
          • 2020-05-04
          • 2014-11-01
          • 1970-01-01
          相关资源
          最近更新 更多