【问题标题】:Use setState on a object of state on ReactJS在 ReactJS 的状态对象上使用 setState
【发布时间】:2018-08-17 06:25:23
【问题描述】:

我用的是ReactJS,需要改变values的状态但是value属性是这样的状态:

this.state = {
         form:{
                name:{
                    value:''
                 }
              }  
         }     

我在表单上以不同的方式尝试过,例如:

<TextInput
 name='form.name.value'
 value={this.state.form.name.value}
 onChange={value => this.onChange('name', value)}
/>


 onChange = (e) => { 
    this.setState({ [e.target.name]: e.target.value})
}  

但永远不会改变状态的值。

我该怎么做?谢谢!!!!!!

【问题讨论】:

  • 你用的是TextInputreact-native还是reactjs?如果reactjs 和自定义input 字段则显示TextInput 的代码。否则 reactjs 输入意味着 HTML 不直接在 onChange 中提供值
  • 文本输入只是 ReactJS 上的一个输入:&lt;div className="input-field"&gt; &lt;i className="material-icons prefix"&gt;{icon}&lt;/i&gt; &lt;input name={name} value={value} onChange={onChange} label={label} type={type} /&gt; &lt;/div&gt;

标签: javascript reactjs state


【解决方案1】:

您使用输入字段名称的方式不正确。在setState 中,它被视为字符串而不是object.key

onChange= (e) => {
    let inputName = e.target.name;
     let inputValue = e.target.value;
     let updatedFormState = Object.assign({}, this.state);
     updatedFormState.form[inputName].value = inputValue;
     this.setState(updatedFormState);
}

【讨论】:

  • 谢谢兄弟,但不起作用:TypeError: Cannot read property 'name' of null
  • @OscarDev 因为 SyntheticEvent 概念,请查看this answer
  • 谢谢你的朋友,这很好用!我将回顾更多关于 Object.assign 的内容,我已经有一段时间没有使用它了。谢谢!
  • 我正在重构,效果很好,非常感谢:let inputName = e.target.name; let inputValue = e.target.value; let form = {...this.state.form} form[inputName].value = inputValue; this.setState(form)
【解决方案2】:

您的onChange 函数应更改为

onChange = (e) => { 
    this.setState({ form: {...this.state.form, [e.target.name]: e.target.value}})
}

编辑:我能够成功运行以下代码

class App extends React.Component {
  state = {
    form: {
       test: ""
    }
  }
  onChange = (e) => {
    this.setState({
      form: {
        ...this.state.form,
        [e.nativeEvent.target.name]: e.target.value,
      }
    })
  }
  render() {
    return <div>
      <TextInput 
       name='test'
       value={this.state.form.test}
       onChange={this.onChange}
      />
      <br/><br/>
      The State : {JSON.stringify(this.state)}
    </div>;
  }
}

const TextInput = (props) => {
  return <input type="text" {...props}/>;
}

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

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

编辑:根据您的新结构,我进行了更改

class App extends React.Component {
  state = {
    form: {
       test: {
         value: "",
         type: "text"
       }
    }
  }
  onChange = (e) => {
    this.setState({
      form: {
        ...this.state.form,
        [e.nativeEvent.target.name]: {
            ...this.state.form[e.nativeEvent.target.name],
            value: e.nativeEvent.target.value
        },
      }
    })
  }
  render() {
    return <div>
      <CustomInput 
       name='test'
       value={this.state.form.test.value}
       onChange={this.onChange}
      />
      <br/><br/>
      The State : {JSON.stringify(this.state)}
    </div>;
  }
}

const CustomInput = (props) => {
  return <input {...props}/>;
}

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

<div id="container"></div>

【讨论】:

  • 我尝试了您的示例,但状态更改如下:State form:{...} name: 'test' 并且丢失了对象。
  • 只要状态类似于:State = { form: { name: " " } } 但如果状态类似于:State = { form: { name: { value=" ", type: " "} } } 您的解决方案将覆盖“名称”对象并使其没有属性:@987654330 @
  • @OscarDev 我添加了修改后的代码 sn-p 以满足您的要求
【解决方案3】:

为了为嵌套对象设置状态,您可以遵循以下方法,因为我认为 setState 不处理嵌套更新。

let form = {...this.state.form}
let name = [e.target.name];
form.name = e.target.value;
this.setState({form});

这个想法是创建一个虚拟对象对其执行操作,然后用更新的对象替换组件的状态

【讨论】:

  • 我试过了,但是如果我添加一个像 form.surname.value 这样的新属性,我只能更改 name 的状态 我不能使用输入文本。
【解决方案4】:

我不知道你的情况,但我认为你的做法是错误的。 解决你的问题:

<TextInput
          name="form.name.value"
          value={this.state.form.name.value}
          onChange={(a, b) => this.handleTextChange(a, b)}
        />

现在handleTextChange点赞

 handleTextChange(name, value) {
    const arr = name.split(".");
    const obj = {
      [arr[2]]: value
    };
    const nameObj = {
      [arr[1]]: { ...obj }
    };

    console.log("fomr", nameObj);
    this.setState({ form: nameObj });
  }

考虑到你自定义组件

const TextInput = props => {
  return (
    <input
      name={props.name}
      onChange={e => props.onChange(e.target.name, e.target.value)}
    />
  );
};

CodeSandbox 工作示例

【讨论】:

  • form.name.value 字符串作为名称出错但可能是因为场景
【解决方案5】:

你需要使用 es6 解构:

我在这里创建了一个工作副本:CodePen InputForm

var sp = {...this.state.form};
sp.name.value = event.target.value;

this.setState({sp})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多