【问题标题】:setState not triggering a re-render when data has been modified修改数据时 setState 不会触发重新渲染
【发布时间】:2015-06-10 03:44:18
【问题描述】:

刚开始使用 React,到目前为止进展相对顺利。

我有一个列表,其中包含 X 个预定义项,这意味着该列表始终以给定数量的行呈现。

此数据是在列表呈现之前从 REST API 收集的。数据包含与列表相关的变量,以及包含列表中每个项目的数组。

我选择了简单的方法,因此我用一个名为“data”的 JSON 对象填充每个组件,该对象包含所有必要的内容。

渲染列表看起来像这样:

<MyList data={data} />

那么,在MyList的getInitialState中:

dataInt: this.props.data.dataInt || 0,
dataStr: this.props.data.dataStr || '',
rows: this.props.data.rows || []

所以我将我的项目数组(JSON)存储在列表(父)的初始状态中,当我选择渲染列表时,我首先在一个数组中创建所有组件(子),如下所示:

var toRender = [];
for(i = 0; i < this.state.rows.length; i++) {
    toRender.push(<ItemRow data={this.state.rows[i]} />);
}

然后我像这样渲染:

return (
    <div className="item-container">
        <table className="item-table">
            {toRender}
        </table>
    </div>
);

MyItem 的渲染函数如下所示:

return (
    <tr>
        <td>{this.state.dataFromItem}</td>
    </tr>
);

现在,假设我想使用我刚刚从 API 获得的一些新数据从父级中修改子级数据。相同的结构,只是一个字段/列的值发生了变化:

i = indexOfItemToBeUpdated;
var newRows = this.state.rows;
newRows[i] = data; // New JSON object with same keys, different values.
this.setState({ rows: newRows }); // Doesn't trigger re-render
this.forceUpdate(); // Doesn't trigger re-render

我做错了什么?

起初我以为是因为我将 MyItem 的渲染函数包装在 a 中,但由于它在初始渲染时渲染得非常好,我会假设这是一个可接受的包装器。

经过一些测试,似乎重新渲染了父视图,而不是子视图(基于父视图中更新的数据)。

JSfiddle:https://jsfiddle.net/zfenub6f/1/

【问题讨论】:

  • 你能不能把它放在一个 jsfiddle 或类似的东西中,因为你不清楚你的实际结构是什么或者这些部分是如何交互的,因为你只包含了一些 sn-ps 代码。
  • 自发布以来我做了一些更改,但同样的问题仍然存在:jsfiddle.net/zfenub6f/1
  • 您能否将其最小化为具体问题并使其真正发挥作用?那里有很多代码,它在 jsfiddle 上不起作用。您可能只需要为每一行添加一个“键”。 facebook.github.io/react/docs/…

标签: javascript json reactjs setstate


【解决方案1】:

我认为问题可能是您仅将getInitialState 用于Row。您正在使用传入的道具设置状态。如果孩子们得到新的道具,getInitialState 将不会再被调用。我总是参考https://facebook.github.io/react/docs/component-specs.html 来查看所有生命周期事件。尝试使用componentWillReceiveProps(object nextProps) 再次设置状态。如果您实际上不需要子级中的state,请删除状态的使用并只使用props,它可能会起作用。

【讨论】:

    【解决方案2】:

    如果你的孩子正在使用状态并且状态没有更新,那么道具呢?这渲染得好吗?如果父级更改了子级的状态并且子级没有反映该更改,则这些子组件很可能需要分配给它们的唯一键,这会告诉 React 当父级上的状态更新时需要更新这些项目。我遇到了一个类似的问题,孩子内部的道具更新以反映父母,但孩子的状态不会更新。一旦我添加了密钥,解决方案就解决了。有关此问题的进一步阅读,请查看最初向我暗示问题的博客。

    http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/

    React 的官方文档也解释了这种情况。

    http://facebook.github.io/react/docs/multiple-components.html#dynamic-children

    【讨论】:

    • 我刚刚更改,只有父级使用状态。然后父级使用“行”的状态版本传递给它的子级。然后,孩子们不会将该值存储在他们自己的状态中,他们只是从道具中渲染。现在问题转移了。现在孩子确实重新渲染,但它重新渲染好像道具是空的。所有渲染的值都是空的。编辑:经过一些额外的调整,它现在可以工作了。我想我以后在使用状态时应该更加小心。感谢您的提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2021-08-04
    • 2020-07-26
    • 2017-06-09
    相关资源
    最近更新 更多