【问题标题】:Reactjs setState issues from form inputs来自表单输入的 Reactjs setState 问题
【发布时间】:2018-04-14 13:50:10
【问题描述】:

我是反应世界的新手,我无法从表单输入字段中正确更改状态。我正在构建一个将保存在数据库中的员工档案。我在组件状态下创建了一个配置文件并从输入字段中获取用户数据。但是,在 OnChange 事件处理函数中,薪水和标题字段并没有改变。候选人是员工的对象表示

this.state = {
  candidate: {
    account: {
      firstName: '',
      lastName: '',
      email: '',
      phone: '',
    },
    salary: '',
    headline: '',
    topSkills: [{
        experience1: '',
        title1: ''
      }, {
        experience2: '',
        title2: ''
      }, {
        experience3: '',
        title3: ''
      },
    ],
  }
}

onChange函数

handleChange(e) {
  const name = e.target.name;
  const value = e.target.value;
  let copyState = Object.assign({},
    this.state.candidate);
  copyState.account[name] = value;
  copyState.topSkills[name] = value;
  copyState.salary = value;
  copyState.headline = value;
  this.setState(copyState);
}

工资和标题中的输入字段不接受用户输入

<input
  name="salary"
  type="number"
  value={this.state.candidate.salary|| ''}
  onChange={this.handleChange}
/>

谁能提供帮助并建议如何在 onChange 函数上构造 setState?

【问题讨论】:

  • 您将状态设置为copyState,而且,为什么要将所有字段设置为value
  • 正如@Daniel Nilles 所说,你很难改变你的状态。如果操作正确,状态会合并更改,您不需要每次都复制整个状态。我建议学习对象传播语法,它对于 React 中的大多数状态变化非常有用。顺便说一句,我也是一个学习者。
  • “工资和标题中的输入字段不接受用户输入”是什么意思?您根本无法输入任何内容吗?您是否尝试输入 $ 或其他货币符号?你试过只输入数字吗?

标签: javascript reactjs onchange


【解决方案1】:

您可以简单地处理输入的类似更改:

state = {
    candidate: {
        account: {
            firstName: '',
            lastName: '',
            email: '',
            phone: '', 
        },
        salary: '',
        headline: '', 
        topSkills: [ 
        {
            experience1: '', 
            title1: ''
        }, 
        {
            experience2: '', 
            title2: ''
        },
        {
            experience3: '', 
            title3: ''
        },
       ],
     }
 }

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

【讨论】:

  • 实际上这不适用于accounttopSkills
  • 哦,是的,我错过了嵌套键和数组的要点。对于动态变化,我们需要考虑另一种方法。感谢您指出这一点。
  • 我会推荐这些字段的子组件...但那是在操作之外
  • @DanielNilles,对于薪水,它应该可以工作,但正如前面的 cmets 中所说,对于其他嵌套字段它不起作用。
【解决方案2】:

SetState 不需要整个对象,只需要您在状态中更新的内容。

根据你已经拥有的,你可以这样做

handleChange(e) {
 const name = e.target.name;
 const value = e.target.value;


 this.setState({
   account[name]: value, 
   topSkills[name]: value, 
   salary: value,
   headline: value, 
 });
}

虽然查看您的实施,但我不确定您是否会在这里实现您想要的...看起来如果您更新薪水,您 account[name]topSkills[name] 和“标题”将更新为您输入的工资值。

正如 devserkan 所说,您可以使用 setState 一次更新一个字段

所以你可以做的是......

<input
 name="salary"
 type="number"
 value={this.state.candidate.salary|| ''}
 onChange={(e)=>this.setState({ salary: e.currentTarget.value })}/>

这有点低效,因为它会在每次渲染时重新创建 onChange 函数。在这种情况下,您在渲染之外创建函数的方法更好......

handleSalaryChange { (e)=>this.setState({ salaray: e.currentTarget.value }); }

handleHeadlineChange { (e)=>this.setState({ headline: e.currentTarget.value }); }

render{ return (
  <div>
    <input
     name="salary"
     type="number"
     value={this.state.candidate.salary|| ''}
     onChange={this.handleSalaryChange)}/>
    <input
     name="headline"
     value={this.state.candidate.headline|| ''}
     onChange={this.handleHeadlineChange)}/>
    ...
  </div>
)}

更新为了使handle*Change 函数能够像当前一样工作,需要更新state 以删除candidate 包装器......

 state = {
    account: {
        firstName: '',
        lastName: '',
        email: '',
        phone: '', 
    },
    salary: '',
    headline: '', 
    topSkills: [ 
    {
        experience1: '', 
        title1: ''
    }, 
    {
        experience2: '', 
        title2: ''
    },
    {
        experience3: '', 
        title3: ''
    },
   ],
 }

【讨论】:

  • 我赞成这个答案,因为我找不到比创建单独的函数来将状态更改为菜鸟更好的解决方案 :) 我认为没有像我一样简单的方法来更改状态普通字段对吗?
  • @Seth McClaine,薪水是候选人变量的一部分,我必须通过候选人才能获得薪水。当状态变量未包含在对象中时,您建议的功能有效
  • @DanielNilles 你是对的,我已经更新了我的回复
【解决方案3】:

感谢 udemy academy MLR — 助教。他这样解决了,答案解决了问题。

handleChange = e => {
            const candidateClone = Object.assign({}, this.state.candidate);// Shallow clone.
            const accountClone = Object.assign({}, this.state.candidate.account);// Deep clone.
            const topSkillsClone = Object.assign({}, this.state.candidate.topSkills);// Deep clone.
            // below (let): Persists the last entered value (required).
            let myHeadline = candidateClone.headline;
            let myFirstName = candidateClone.account.firstName;
            let mySalary = candidateClone.salary;
            let myTopSkillsTitle = candidateClone.topSkills[0].title;
            switch (e.target.name) {
                case "headlineInput": // name in input field
                    myHeadline = e.target.value;
                    break;
                case "firstNameInput": // name in input field
                    myFirstName = e.target.value;
                    break;
                case "salaryInput":
                    mySalary = e.target.value;
                    break;
                case "topSkillsTitleInput": // name in input field 
                    myTopSkillsTitle = e.target.value;
                    break;
                default:
                    console.log("Switch statement error");
            }
            accountClone.firstName = myFirstName;// Place the property value inside the deep cloned embedded object.
            topSkillsClone[0].title = myTopSkillsTitle;// Place the property value inside the deep cloned embedded array.
            candidateClone["account"] = accountClone;// Place the deep cloned embedded object inside the shallow cloned main object.
            candidateClone["salary"] = mySalary;// Place the property inside the shallow cloned main object.
            candidateClone["headline"] = myHeadline;// Place the property inside the shallow cloned main object.
            candidateClone["topSkills"] = topSkillsClone;// Place the deep cloned embedded array inside the shallow cloned main object.
            this.setState({candidate:candidateClone});
        };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-02
    • 2019-02-13
    • 1970-01-01
    • 2020-06-09
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多