【问题标题】:React Hooks: setState hook inside map functionReact Hooks:地图函数内的 setState 钩子
【发布时间】:2020-05-19 13:31:44
【问题描述】:

我目前正在努力解决 setState 与表单的异步性质,我的预期行为是,当用户单击 submitForm 按钮时,它会检查状态内的所有表单值,如果该值为空,则它会为此设置 errorState特定的表单元素,以便出现错误消息

  const [values, setValues] = React.useState({
    firstName: '',
    lastName: '',
    id: '',
    city: '',
    emailAddress:'',
    mobileNumber: ''
  });

  const [errors, setError] = React.useState({
    firstName: false,
    lastName: false,
    id: false,
    city: false,
    emailAddress: false,
    mobileNumber: false
  })

  const submitForm = () => {
    const setErrorArray = Object.keys(values).map((key) => {
      if (values[key] === '') {
        setError({...errors, [key]: true })
      }
    });
  }

我认为问题是由于 setState 是异步的,因此在 .map 完成后,它只将错误对象内的最后一个值设置为 true(因此 errors.mobileNumber = true)。而不是使所有符合条件的值都为真。扩展运算符 {...errors} 将值覆盖为初始 false 值。如果 values 数组中的值为空,是否有办法实现错误中的每个键都设置为 true ??

任何帮助将不胜感激

【问题讨论】:

  • 每次调用setError 时,都会使用相同的原始errors 和一个新值。为什么不构建一个对象newErrors 然后在.map 之后 做一个setError({ ...errors, ...newErrors })?另请注意,您实际上并未使用其返回值的.map(在本例中为undefined 的数组)应该是.forEach
  • 您应该查看useReducer 作为此问题的可能解决方案。
  • 使用受控输入会更好。

标签: javascript reactjs forms react-hooks setstate


【解决方案1】:

我会通过映射值的条目来立即构造全新的错误对象,然后您可以使用该对象调用setError

const values = {
    firstName: 'first',
    lastName: 'last',
    id: '',
    city: '',
};
const newErrors = Object.fromEntries(
  Object.entries(values).map(
    ([key, val]) => [key, val === '']
  )
);
console.log(newErrors);
// setError(newErrors);

【讨论】:

    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2019-09-07
    • 2016-03-10
    • 2020-12-17
    • 2020-09-14
    相关资源
    最近更新 更多