【问题标题】:Issue with this.props properties not existing even though they dothis.props 属性不存在的问题,即使它们存在
【发布时间】:2016-11-09 18:12:01
【问题描述】:

是的,这是一个地狱般的名字。但在我的状态下,我就是想不出一个更好的标题。

问题如下。

在 React 中,在 componentWillMount 期间,我将状态初始化为 null,然后在通过 ajax 从服务器拉取数据后更新该状态。

结构如下:

  componentWillMount() {
    this.state = { calculator: {} };

  initCalculator()
    .then(calculator => {
      this.setState({ calculator });
    })
    .catch(err => {
      console.log(err);
    });
  }

数据本身被拉到这里:

  function initCalculator() {
    const promise = new Promise((resolve, reject) => {
      const instance = parseInstance();
      const compId = Wix.Utils.getOrigCompId();

      axios.get(`/api/calculator?instance=${instance}&compId=${compId}`)
        .then(res => {
          resolve(res.data);
        })
        .catch(err => {
          reject(err);
        });
    });

    return promise;
  }

res.data 是带有来自服务器的数据的响应对象。

然后,如您在上面看到的,此数据将传递给 state。

这个状态数据然后被传递给另一个元素:

<Settings tab="Settings" calculator={ this.state.calculator } onUpdate={ this.settingsUpdate.bind(this) }/>

但是,数据并没有在“设置”选项卡的另一端“解析”。

每当我尝试访问计算器对象深处的属性时,它总是向我抛出一个错误。

cannot read property settings of null

这里可以看到

const name = this.props.calculator.settings ? this.props.calculator.settings.name : '';

所以,如果我尝试访问 calculator.settings.name,它会向我抛出类似的错误。

此外,const name 始终设置为 '',即使在第二次重新渲染期间,当推测数据应该已经可用时,因为状态已更新,从而提示在子节点中重新渲染元素。

我明白为什么会这样。至少有点。该对象在它被解析之前被传递,因此在第二次状态更改期间,即this.setState({ calculator });,在状态完全更新之前调用重新渲染。至少我是这么认为的。

如果我console.log(this.props.calculator),我可以正常查看所有数据。但是因为console.log,在点击箭头展开详细信息的同时,它会解析数据。

如果我选择JSON.stringify(this.props.calculator),则数据将全部显示并可用。现在我知道我可以使用JSON.stringifyJSON.parse 来解决这个问题。但这只是解决我自己可能创造的此类问题的愚蠢方法。

我了解对象通过引用起作用。所以我认为问题出在初始 ajax get 请求或 setState 方法中。

也许有敏锐眼光的人能够看出这里的问题所在。但在这一点上,我只是把头撞在墙上。

【问题讨论】:

  • 经过更多测试,我可以得出结论,确实是this.setState(...); 导致了问题。在重新渲染子组件之前,它没有足够快地更新状态。因此,孩子仍然收到状态的旧副本。还没想出解决办法。
  • 好吧,所以解决方案似乎是为了在状态更新时更新和重新渲染元素,在某些情况下,您需要在组件上使用key 属性。我会进一步测试它,明天提交我自己问题的答案。
  • 谢谢,是的,我本可以返回原始的axios.get(...),并且功能相同。

标签: javascript ajax reactjs


【解决方案1】:

constructor 而不是componentWillMount 中设置您的状态。在 componentDidMount 上进行 ajax 调用,并在成功请求时更新您的状态。

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

     componentWillMount() {

     }

     updataStateFromCompletedAjax(data) {
      this.setState({
       data: data
      })
     }

【讨论】:

  • componentDidMount 而不是 componentWillMount 中调用异步函数有什么真正的区别吗?还是一般来说只是更好的做法?
  • 老实说,它主要是最佳实践,但这个问题打破了差异。 stackoverflow.com/questions/29899116/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多