反应:如何使用setState更新state.item [1]状态?


258

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

该组件在此处可作为JSFiddle使用。

我的初始状态如下:

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

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

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

我应该如何this.setState进行更新items[1].name



1
您为该问题选择的答案是什么?
Braian Mellor

Answers:


126

您可以update为此使用不变性帮助器

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中学习简单组件通信”课程,以获取如何将回调函数从保持状态的父级传递到需要触发状态更改的子级组件的示例。


125

由于此线程中存在很多错误信息,因此可以在没有辅助库的情况下执行以下操作:

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

4
@TranslucentCloud哦,是的,辅助方法绝对不错,但是我认为每个人都应该知道
幕后的情况

为什么我们需要步骤2和3?为什么我们不能在第一步之后直接突变克隆?
伊夫莫罗夫'18

1
@Evmorov,因为它不是深度克隆。步骤1只是克隆数组,而不是克隆其中的对象。换句话说,新数组中的每个对象仍然“指向”内存中的现有对象-改变一个将改变另一个(它们是相同的)。另请参阅items[0] === clone[0]底部我的终端示例中的位。三重=检查对象是否引用相同的事物。
mpen

如果您不知道数组中项目的索引,它将变得更加复杂。
伊恩·沃伯顿

@IanWarburton不是。items.findIndex()应该做的简短。
mpen19年

92

错误的方法!

handleChange = (e) => {
    const { items } = this.state;
    items[1].name = e.target.value;

    // update state
    this.setState({
        items,
    });
};

正如许多更好的开发人员在评论中指出的:改变状态是错误的!

花了我一段时间来解决这个问题。以上工作,但它带走了React的力量。例如componentDidUpdate由于它是直接修改的,因此不会将其视为更新。

因此正确的方法是:

handleChange = (e) => {
    this.setState(prevState => ({
        items: {
            ...prevState.items,
            [prevState.items[1].name]: e.target.value,
        },
    }));
};

25
ES6仅仅因为您使用的是“ const”?
nkkollaw

49
items[1].role = e.target.value直接调用变异状态吗?
Antony

28
您正在改变状态,这完全与保持状态不变(如建议的反应)的想法相反。在大型应用程序中,这可能会给您带来很多痛苦。
ncubica '17

8
@MarvinVK,您的回答是:“最佳实践是:”,然后使用“ this.forceUpdate();”。不建议这样做,因为它可能会被setState()覆盖,请参阅facebook.github.io/react/docs/react-component.html#state。最好对此进行更改,以免对未来的读者造成困扰。
James Z.

7
只是想指出,由于编辑,许多评论现在已经不相关了,正确的方法实际上是正确的方法。
heez

50

要在React状态下修改深层嵌套的对象/变量,通常使用三种方法:vanilla JavaScript的Object.assignimmutability -helpercloneDeep来自Lodash的方法

还有许多其他较不受欢迎的第三方库可以实现此目的,但是在此答案中,我将仅介绍这三个选项。此外,还存在一些其他的普通JavaScript方法,例如数组扩展(例如,参见@mpen的答案),但是它们不是非常直观,易于使用并且能够处理所有状态操纵情况。

正如人们在回答问题的最高票数评论中指出的那样,无数次,他们的作者提出了国家的直接突变:只是不要那样做。这是无处不在的React反模式,将不可避免地导致不良后果。学习正确的方法。

让我们比较三种广泛使用的方法。

给定此状态对象结构:

state = {
    outer: {
        inner: 'initial value'
    }
}

您可以使用以下方法更新最里面的 inner字段的值,而不会影响其余状态。

1. Vanilla JavaScript的Object.assign

const App = () => {
  const [outer, setOuter] = React.useState({ inner: 'initial value' })

  React.useEffect(() => {
    console.log('Before the shallow copying:', outer.inner) // initial value
    const newOuter = Object.assign({}, outer, { inner: 'updated value' })
    console.log('After the shallow copy is taken, the value in the state is still:', outer.inner) // initial value
    setOuter(newOuter)
  }, [])

  console.log('In render:', outer.inner)

  return (
    <section>Inner property: <i>{outer.inner}</i></section>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('react')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>

<main id="react"></main>

请记住,Object.assign 将不执行深度克隆,因为它仅复制属性值,因此这就是所谓的浅复制(请参见注释)的原因。

为此,我们应该只操作基本类型(outer.inner)的属性,即字符串,数字,布尔值。

在这个例子中,我们创建一个新的常数(const newOuter...),使用Object.assign,它创建一个空的对象({}),拷贝outer对象({ inner: 'initial value' })到它,然后复制一个不同的对象{ inner: 'updated value' } 吧。

这样,最后newOuter{ inner: 'updated value' }由于该inner属性被覆盖,新创建的常量将保留一个值。这newOuter是一个全新的对象,它没有链接到处于状态的对象,因此可以根据需要对其进行更改,并且状态将保持不变,并且在运行更新该对象的命令之前不会更改。

最后一部分是使用setOuter()setter outer将状态为原始的newOuter对象替换为新创建的对象(仅值会更改,属性名称outer不会)。

现在想象我们有一个更深的状态,如state = { outer: { inner: { innerMost: 'initial value' } } }。我们可以尝试创建该newOuter对象并使用outer状态中的内容填充它,但是由于以下原因,Object.assign将无法将innerMost的值复制到此新创建的newOuter对象中:innerMost嵌套太深。

您仍然可以inner像上面的示例中那样进行复制,但是由于它现在是对象而不是原始对象,因此from 的引用newOuter.inner将被复制到对象outer.inner,这意味着我们最终将newOuter在状态下将本地对象直接绑定到该对象。

这意味着在这种情况下,本地创建的突变newOuter.inner将直接影响outer.inner对象(处于状态),因为实际上它们已成为同一事物(位于计算机的内存中)。

Object.assign 因此,仅当您具有一个相对简单的一级深度状态结构且其最内部的成员保存原始类型的值时,该结构才起作用。

如果您有更深的对象(第2级或更高级别)需要更新,请不要使用Object.assign。您有直接改变状态的风险。

2. Lodash的cloneDeep

const App = () => {
  const [outer, setOuter] = React.useState({ inner: 'initial value' })

  React.useEffect(() => {
    console.log('Before the deep cloning:', outer.inner) // initial value
    const newOuter = _.cloneDeep(outer) // cloneDeep() is coming from the Lodash lib
    newOuter.inner = 'updated value'
    console.log('After the deeply cloned object is modified, the value in the state is still:', outer.inner) // initial value
    setOuter(newOuter)
  }, [])

  console.log('In render:', outer.inner)

  return (
    <section>Inner property: <i>{outer.inner}</i></section>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('react')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

<main id="react"></main>

Lodash的cloneDeep使用起来更简单。它执行如果您的状态相当复杂,并且内部具有多级对象或数组,则深度克隆,因此这是一个可靠的选择。只是cloneDeep()顶层状态属性,以您喜欢的任何方式对克隆的部分进行突变,然后setOuter()其恢复为状态。

3. 不变性的帮助者

const App = () => {
  const [outer, setOuter] = React.useState({ inner: 'initial value' })
  
  React.useEffect(() => {
    const update = immutabilityHelper
    console.log('Before the deep cloning and updating:', outer.inner) // initial value
    const newOuter = update(outer, { inner: { $set: 'updated value' } })
    console.log('After the cloning and updating, the value in the state is still:', outer.inner) // initial value
    setOuter(newOuter)
  }, [])

  console.log('In render:', outer.inner)

  return (
    <section>Inner property: <i>{outer.inner}</i></section>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('react')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>
<script src="https://wzrd.in/standalone/immutability-helper@3.0.0"></script>

<main id="react"></main>

immutability-helper它需要一个全新的水平,而关于它的很酷的事情是,它不仅能$set值状态的项目,也是$push$splice$merge(等)它们。这是可用命令列表

旁注

同样,请记住,这setOuter只会修改状态对象的第一级属性outer在这些示例中),而不修改深度嵌套的(outer.inner)。如果它的行为方式不同,则该问题将不存在。

哪一个是对的为您的项目?

如果您不想或不能使用外部依赖项,并且具有简单的状态结构,请坚持Object.assign

如果您操纵巨大和/或复杂的状态,Lodash的cloneDeep选择是一个明智的选择。

如果您需要高级功能,即状态结构很复杂并且需要对其执行各种操作,请尝试immutability-helper,它是一种非常先进的工具,可用于状态处理。

...或者,您真的需要这样做吗?

如果您将复杂数据保存在React的状态下,也许现在正是考虑其他处理方式的好时机。在React组件中设置复杂的状态对象并不是一项简单的操作,我强烈建议考虑使用不同的方法。

您很可能最好将复杂数据保留在Redux存储中,使用reducer和/或sagas在那里进行设置,并使用选择器进行访问。


Object.assign不执行深层复制。假设,如果a = {c: {d: 1}}b = Object.assign({}, a),则执行b.c.d = 4,然后a.c.d被突变。
Awol

没错,1最里面的对象(a.c.d)的值将发生突变。但是,如果您要b像这样重新分配的第一级后继者b.c = {f: 1},则的相应部分a将不会发生突变(它将保持{d: 1})。不管怎么说,我会立即更新答案。
神经递质

您定义的实际上是a shallow copy而不是a deep copy。很容易混淆shallow copy含义。在shallow copya !== b,但是对于源对象中的每个键aa[key] === b[key]
Awol

是的,Object.assign答案中明确提到了的肤浅性。
Neurotransmitter

JSON.parse(JSON.stringify(object))也是深度克隆的变体。但是,性能却差强人意cloneDeepmeasurethat.net/Benchmarks/Show/2751/0/…–
tylik

35

我有同样的问题。这是一个可行的简单解决方案!

const newItems = [...this.state.items];
newItems[item] = value;
this.setState({ items:newItems });

11
@TranslucentCloud-这肯定不是直接的突变。克隆,修改原始阵列,然后使用克隆的阵列再次设置状态。
vsync

@vsync是的,现在您编辑完原始答案后,这根本不是突变。
神经递质

2
@TranslucentCloud-在此之前,我的编辑与之无关,非常感谢您的态度。@Jonas在这里只是在回答中犯了一个简单的错误,使用{花括号而不是我已经纠正的括号
vsync

31

根据关于setState的React文档,Object.assign按此处其他答案的建议使用不是理想的。由于性质setState异步行为使用此技术的后续调用可能会覆盖先前的调用,从而导致不良后果。

相反,React docs建议使用更新器形式,setState该形式在先前状态下运行。请记住,在更新数组或对象时,您必须返回一个新的数组或对象,因为React要求我们保留状态不变性。使用ES6语法的spread运算符浅表复制数组,在数组的给定索引处创建或更新对象的属性,如下所示:

this.setState(prevState => {
    const newItems = [...prevState.items];
    newItems[index].name = newName;
    return {items: newItems};
})

2
如果使用ES6,这是合适的答案。@Jonas回答的内容是内联的。但是由于解释,它很突出。
Sourabh

是的,这代码工作完全正常和非常简单的..
Shoeb米尔扎

29

首先获取所需的项目,更改该对象的所需内容,然后将其重新设置为状态。getInitialState如果您要使用键控对象,则仅通过传入对象来使用状态的方式会更容易。

handleChange: function (e) {
   item = this.state.items[1];
   item.name = 'newName';
   items[1] = item;

   this.setState({items: items});
}

3
不,它产生了Uncaught TypeError: Cannot read property 'items' of null
马丁斯

不,不会。您的错误很可能源于您的操作方式getInitialState
Henrik Andersson

10
@HenrikAndersson在您的示例中似乎不正确。items没有在任何地方定义。
Edward D'Souza

1
@ EdwardD'Souza你绝对正确!我的答案是显示应该如何定义和使用它。询问者代码的设置方式不适用于他/她想要的事情,这就是为什么需要键控对象的原因。
亨里克·安德森

7
这是典型的React反模式,您要item为状态自己的this.state.items[1]变量分配一个引用。然后,您修改itemitem.name = 'newName'),从而直接更改状态,强烈建议您不要这样做。在您的示例中,甚至不需要调用this.setState({items: items}),因为状态已经直接突变。
神经递质

22

不要改变状态。可能会导致意外结果。我学到了教训!始终使用副本/克隆,这Object.assign()是一个很好的选择:

item = Object.assign({}, this.state.items[1], {name: 'newName'});
items[1] = item;
this.setState({items: items});

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


8
是什么items在你的榜样?你的意思this.state.items是别的吗?
Buh Buh

我对此进行了测试,但他错过了一行。上面items[1] = item;应该有一行话items = this.state.items;。当心我的JavaScript生锈了,我正在学习对我的家庭项目做出反应,所以我不知道这是好是坏:-)
Greg0ry

4

真的很简单。

首先,从状态中拉出整个项目对象,根据需要更新项目对象的一部分,然后通过setState将整个项目对象恢复为状态。

handleChange: function (e) {
  items = Object.assign(this.state.items); // Pull the entire items object out. Using object.assign is a good idea for objects.
  items[1].name = 'newName'; // update the items object as needed
  this.setState({ items }); // Put back in state
}

“如果您具有一个相对简单的一级深度状态结构,并且最内部的成员持有原始类型的值,则Object.assign将起作用”。
神经递质

3

由于上述选项都不是我理想的选择,因此我最终使用了map:

this.setState({items: this.state.items.map((item,idx)=> idx!==1 ?item :{...item,name:'new_name'}) })

2

无突变:

// given a state
state = {items: [{name: 'Fred', value: 1}, {name: 'Wilma', value: 2}]}

// This will work without mutation as it clones the modified item in the map:
this.state.items
   .map(item => item.name === 'Fred' ? {...item, ...{value: 3}} : item)

this.setState(newItems)

2
我看不到newItems设置在哪里。
Neurotransmitter

数组中的映射加比较对性能来说不是很可怕吗?
Natassia Tavares

@NatassiaTavares ..什么?也许您感到困惑,fo of或者forEach地图是最快的。
Deano

1

发现这一点非常困难,而且ES6传播魔术似乎都没有按预期工作。使用这样的结构来获取渲染的元素属性以用于布局。

在此简化示例中,发现使用update方法from immutability-helper是最直接的方法:

constructor(props) {
    super(props)
    this.state = { values: [] }
    this.updateContainerState = this.updateContainerState.bind(this)
  }

updateContainerState(index, value) {
    this.setState((state) => update(state, { values: { [index]: { $set: value } } }))
  }

摘自https://github.com/kolodny/immutability-helper#computed-property-names

要更新的数组成员的组成部分是更嵌套的复杂对象,请使用适当的深度复制方法基于复杂度。

当然有更好的方法来处理布局参数,但这是关于如何处理数组的。每个子元素的相关值也可以在它们之外进行计算,但是我发现将containerState向下传递更方便,因此它们的子元素可以随意获取属性,并在给定索引处更新父状态数组。

import React from 'react'
import update from 'immutability-helper'
import { ContainerElement } from './container.component.style.js'
import ChildComponent from './child-component'
export default class ContainerComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { values: [] }
    this.updateContainerState = this.updateContainerState.bind(this)
  }

  updateContainerState(index, value) {
    this.setState((state) => update(state, { values: { [index]: { $set: value } } }))
  }

  // ...

  render() {
    let index = 0
    return (
      <ContainerElement>
      <ChildComponent
        index={index++}
        containerState={this.state}
        updateContainerState={this.updateContainerState}
      />
      <ChildComponent
        index={index++}
        containerState={this.state}
        updateContainerState={this.updateContainerState}
      />
      </ContainerElement>
    )
  }
}

1

在一行中使用带有箭头功能的数组映射

this.setState({
    items: this.state.items.map((item, index) =>
      index === 1 ? { ...item, name: 'newName' } : item,
   )
})

1
这与大约一年前发布的其他答案基本相同
SomePerformance


0

我将移动函数句柄更改并添加索引参数

handleChange: function (index) {
    var items = this.state.items;
    items[index].name = 'newName';
    this.setState({items: items});
},

到动态表单组件,并将其作为道具传递给PopulateAtCheckboxes组件。当您遍历项目时,可以包括一个额外的计数器(在下面的代码中称为索引),该计数器将传递给句柄更改,如下所示

{ Object.keys(this.state.items).map(function (key, index) {
var item = _this.state.items[key];
var boundHandleChange = _this.handleChange.bind(_this, index);
  return (
    <div>
        <PopulateAtCheckboxes this={this}
            checked={item.populate_at} id={key} 
            handleChange={boundHandleChange}
            populate_at={data.populate_at} />
    </div>
);
}, this)}

最后,您可以按如下所示呼叫变更侦听器

<input type="radio" name={'populate_at'+this.props.id} value={value} onChange={this.props.handleChange} checked={this.props.checked == value} ref="populate-at"/>

切勿直接改变React的状态。
神经递质

0

如果您只需要更改的一部分,则Array可以将状态设为的React组件。

state = {items: [{name: 'red-one', value: 100}, {name: 'green-one', value: 999}]}

这是最好的更新red-oneArray,如下所示:

const itemIndex = this.state.items.findIndex(i=> i.name === 'red-one');
const newItems = [
   this.state.items.slice(0, itemIndex),
   {name: 'red-one', value: 666},
   this.state.items.slice(itemIndex)
]

this.setState(newItems)

是什么newArray?你的意思是newItems?如果这样做,那以后不就只剩下一项吗?
micnil

这将引入一个新的属性newItemsstate对象,而不会更新现有的items财产。
Neurotransmitter

0

或者,如果您有一个动态生成的列表,但您不知道索引,而只有键或ID:

let ItemsCopy = []
let x = this.state.Items.map((entry) =>{

    if(entry.id == 'theIDYoureLookingFor')
    {
        entry.PropertyToChange = 'NewProperty'
    }

    ItemsCopy.push(entry)
})


this.setState({Items:ItemsCopy});

0

尝试使用代码:

this.state.items[1] = 'new value';
var cloneObj = Object.assign({}, this.state.items);

this.setState({items: cloneObj });

0

在我沉闷的大脑中,遵循以下代码很容易。删除对象并替换为更新的对象

    var udpateditem = this.state.items.find(function(item) { 
                   return item.name == "field_1" });
    udpateditem.name= "New updated name"                       
    this.setState(prevState => ({                                   
    items:prevState.dl_name_template.filter(function(item) { 
                                    return item.name !== "field_1"}).concat(udpateditem)
    }));

0

如何创建另一个组件(用于需要进入数组的对象)并将以下内容作为道具传递呢?

  1. 组件索引-索引将用于在数组中创建/更新。
  2. set函数-此函数根据组件索引将数据放入数组。
<SubObjectForm setData={this.setSubObjectData}                                                            objectIndex={index}/>

这里可以根据使用此SubObjectForm的位置传递{index}。

和setSubObjectData可以是这样的。

 setSubObjectData: function(index, data){
      var arrayFromParentObject= <retrieve from props or state>;
      var objectInArray= arrayFromParentObject.array[index];
      arrayFromParentObject.array[index] = Object.assign(objectInArray, data);
 }

在SubObjectForm中,可以在更改数据时调用this.props.setData,如下所示。

<input type="text" name="name" onChange={(e) => this.props.setData(this.props.objectIndex,{name: e.target.value})}/>

0
this.setState({
      items: this.state.items.map((item,index) => {
        if (index === 1) {
          item.name = 'newName';
        }
        return item;
      })
    });

1
这不是最佳选择,您迭代整个数组以仅更新第二项?
wscourge

您还需要在第一个数组中进行元素变异,因此应使用item = Object.assign({}, item, {name: 'newName'});
remram

0

@JonnyBuchanan的答案很完美,但仅适用于数组状态变量。如果状态变量只是一个字典,请遵循以下步骤:

inputChange = input => e => {
    this.setState({
        item: update(this.state.item, {[input]: {$set: e.target.value}})
    })
}

您可以用[input]字典的字段名称e.target.value及其值替换。此代码在我的表单的输入更改事件上执行更新作业。


-3

试试这个,它肯定会工作,其他情况下我试过但没用

import _ from 'lodash';

this.state.var_name  = _.assign(this.state.var_name, {
   obj_prop: 'changed_value',
});

切勿直接改变React的状态。
神经递质

-3
 handleChanges = (value, key) => {
     // clone the current State object
    let cloneObject = _.extend({}, this.state.currentAttribute);
    // key as user.name and value= "ABC" then current attributes have current properties as we changes
    currentAttribute[key] = value;
    // then set the state "currentAttribute" is key and "cloneObject" is changed object.  
    this.setState({currentAttribute: cloneObject});

并从文本框中更改添加onChange事件

onChange = {
   (event) => {                                                
      this.handleChanges(event.target.value, "title");
   }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.