React:如何使用 setState 更新 state.item[1] 状态? [英] React: how to update state.item[1] in state using setState?

查看:33
本文介绍了React:如何使用 setState 更新 state.item[1] 状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,用户可以在其中设计自己的表单.例如.指定字段的名称以及应包含哪些其他列的详细信息.

该组件可用作 JSFiddle 此处.

我的初始状态如下:

var DynamicForm = React.createClass({getInitialState:函数(){var 项目 = {};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: '用户名',autocomplete_from: 'user_name', title: '' };退换货品 };},渲染:函数(){var _this = this;返回 (<div>{ Object.keys(this.state.items).map(function (key) {var item = _this.state.items[key];返回 (<div><PopulateAtCheckboxes this={this}已检查={item.populate_at} id={key}populate_at={data.populate_at}/>

);}, 这个)}<button onClick={this.newFieldEntry}>创建一个新字段</button><button onClick={this.saveAndContinue}>保存并继续</button>

);}

我想在用户更改任何值时更新状态,但我很难定位到正确的对象:

var PopulateAtCheckboxes = React.createClass({handleChange:函数(e){item = this.state.items[1];item.name = 'newName';项目[1] = 项目;this.setState({items: items});},渲染:函数(){var populateAtCheckbox = this.props.populate_at.map(function(value) {返回 (<label for={value}><input type="radio" name={'populate_at'+this.props.id} value={value}onChange={this.handleChange} 选中={this.props.checked == value}ref="populate-at"/>{价值});}, 这个);返回 (<div className="populate-at-checkboxes">{populateAtCheckbox}

);}});

我应该如何制作 this.setState 以使其更新 items[1].name ?

解决方案

由于此线程中有很多错误信息,以下是没有帮助库的方法:

handleChange:函数(e){//1. 制作项目的浅拷贝让 items = [...this.state.items];//2. 制作一个你想要变异的项目的浅拷贝让 item = {...items[1]};//3. 替换你感兴趣的属性item.name = 'newName';//4. 将它放回我们的数组中.注意我们*正在*改变这里的数组,但这就是我们首先复制的原因项目[1] = 项目;//5. 将状态设置为我们的新副本this.setState({items});},

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

let item = {...项目[1],名称:'新名称'}

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

this.setState(({items}) => ({项目: [...items.slice(0,1),{...项目[1],名称:'新名称',},...items.slice(2)]}));

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

<小时>

您可以在终端/控制台中看到正在发生的事情:

❯节点>items = [{name:'foo'},{name:'bar'},{name:'baz'}][ {名称:'foo'},{名称:'bar'},{名称:'baz'}]>克隆 = [...项目][ {名称:'foo'},{名称:'bar'},{名称:'baz'}]>item1 = {...克隆[1]}{名称:'酒吧'}>item1.name = '培根''熏肉'>克隆 [1] = 项目 1{名称:'培根'}>克隆[ {名称:'foo'},{名称:'培根'},{名称:'baz'}]>项目[ { name: 'foo' }, { name: 'bar' }, { name: 'baz' } ]//好!我们没有改变`items`>项目 === 克隆false//这些是不同的对象>项目[0] === 克隆[0]true//我们不需要克隆项目 0 和 2,因为我们没有改变它们(效率提升!)>项目[1] === 克隆[1]false//我们复制的这个家伙

I'm creating an app where the user can design his own form. E.g. specify name of the field and details of which other columns that should be included.

The component is available as a JSFiddle here.

My initial state looks like this:

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 (
       <div>
         { Object.keys(this.state.items).map(function (key) {
           var item = _this.state.items[key];
           return (
             <div>
               <PopulateAtCheckboxes this={this}
                 checked={item.populate_at} id={key} 
                   populate_at={data.populate_at} />
            </div>
            );
        }, this)}
        <button onClick={this.newFieldEntry}>Create a new field</button>
        <button onClick={this.saveAndContinue}>Save and Continue</button>
      </div>
    );
  }

I want to update the state when the user changes any of the values, but I'm having a hard time to target the correct object:

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 (
        <label for={value}>
          <input type="radio" name={'populate_at'+this.props.id} value={value}
            onChange={this.handleChange} checked={this.props.checked == value}
            ref="populate-at"/>
          {value}
        </label>
      );
    }, this);
    return (
      <div className="populate-at-checkboxes">
        {populateAtCheckbox}
      </div>
    );
  }
});

How should I craft this.setState to get it to update items[1].name ?

解决方案

Since there's a lot of misinformation in this thread, here's how you can do it without helper libs:

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});
},

You can combine steps 2 and 3 if you want:

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

Or you can do the whole thing in one line:

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

Note: I made items an array. OP used an object. However, the concepts are the same.


You can see what's going on in your terminal/console:

❯ 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

这篇关于React:如何使用 setState 更新 state.item[1] 状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆