如何使用 setState 更新状态中的 state.item?
P粉464208937
P粉464208937 2023-08-23 17:35:11
[React讨论组]
<p>我正在创建一个应用程序,用户可以在其中设计自己的表单。例如。指定字段的名称以及应包含的其他列的详细信息。</p> <p>该组件可作为 JSFiddle 使用。</p> <p>我的初始状态如下所示:</p> <pre class="brush:php;toolbar:false;">var DynamicForm = React.createClass({ getInitialState: function() { var items = {}; items[1] = { name: 'field 1', populate_at: 'web_start', same_as: 'customer_name', autocomplete_from: 'customer_name', title: '' }; items[2] = { name: 'field 2', populate_at: 'web_end', same_as: 'user_name', autocomplete_from: 'user_name', title: '' }; return { items }; }, render: function() { var _this = this; return ( &lt;div&gt; { Object.keys(this.state.items).map(function (key) { var item = _this.state.items[key]; return ( &lt;div&gt; &lt;PopulateAtCheckboxes this={this} checked={item.populate_at} id={key} populate_at={data.populate_at} /&gt; &lt;/div&gt; ); }, this)} &lt;button onClick={this.newFieldEntry}&gt;Create a new field&lt;/button&gt; &lt;button onClick={this.saveAndContinue}&gt;Save and Continue&lt;/button&gt; &lt;/div&gt; ); }</pre> <p>我想在用户更改任何值时更新状态,但我很难定位正确的对象:</p> <pre class="brush:php;toolbar:false;">var PopulateAtCheckboxes = React.createClass({ handleChange: function (e) { item = this.state.items[1]; item.name = 'newName'; items[1] = item; this.setState({items: items}); }, render: function() { var populateAtCheckbox = this.props.populate_at.map(function(value) { return ( &lt;label for={value}&gt; &lt;input type="radio" name={'populate_at'+this.props.id} value={value} onChange={this.handleChange} checked={this.props.checked == value} ref="populate-at"/&gt; {value} &lt;/label&gt; ); }, this); return ( &lt;div className="populate-at-checkboxes"&gt; {populateAtCheckbox} &lt;/div&gt; ); } });</pre> <p>我应该如何制作<code>this.setState</code>以使其更新<code>items[1].name</code>?</p>
P粉464208937
P粉464208937

全部回复(2)
P粉798343415

您可以使用更新不变性助手来实现此目的: p>

this.setState({
  items: update(this.state.items, {1: {name: {$set: 'updated field name'}}})
})

或者,如果您不关心是否能够使用 ===shouldComponentUpdate() 生命周期方法中检测此项的更改,则可以编辑状态直接并强制组件重新渲染 - 这实际上与 @limelights 的答案相同,因为它将对象拉出状态并对其进行编辑。

this.state.items[1].name = 'updated field name'
this.forceUpdate()

后期编辑添加:

查看简单组件通信 react-training 中的课程,了解如何将回调函数从持有状态的父组件传递到子组件的示例需要触发状态更改。

P粉709307865

以下是在没有辅助库的情况下如何做到这一点:

handleChange: function (e) {
    // 1. Make a shallow copy of the items
    let items = [...this.state.items];
    // 2. Make a shallow copy of the item you want to mutate
    let item = {...items[1]};
    // 3. Replace the property you're intested in
    item.name = 'newName';
    // 4. Put it back into our array. N.B. we *are* mutating the array here, 
    //    but that's why we made a copy first
    items[1] = item;
    // 5. Set the state to our new copy
    this.setState({items});
},

如果需要,您可以合并步骤 2 和 3:

let item = {
    ...items[1],
    name: 'newName'
}

或者你可以在一行中完成整个事情:

this.setState(({items}) => ({
    items: [
        ...items.slice(0,1),
        {
            ...items[1],
            name: 'newName',
        },
        ...items.slice(2)
    ]
}));

注意:我将 items 创建为一个数组。 OP使用了一个对象。但是,概念是相同的。


您可以看到终端/控制台中发生了什么:

❯ node
> items = [{name:'foo'},{name:'bar'},{name:'baz'}]
[ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ]
> clone = [...items]
[ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ]
> item1 = {...clone[1]}
{ name: 'bar' }
> item1.name = 'bacon'
'bacon'
> clone[1] = item1
{ name: 'bacon' }
> clone
[ { name: 'foo' }, { name: 'bacon' }, { name: 'baz' } ]
> items
[ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ] // good! we didn't mutate `items`
> items === clone
false // these are different objects
> items[0] === clone[0]
true // we don't need to clone items 0 and 2 because we're not mutating them (efficiency gains!)
> items[1] === clone[1]
false // this guy we copied
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号