React Hooks 表单处理:使用多个字符串项和一个数组项更新对象的状态

Posted

技术标签:

【中文标题】React Hooks 表单处理:使用多个字符串项和一个数组项更新对象的状态【英文标题】:React Hooks Form Handling: Update the state of an object with multiple string items and one array item 【发布时间】:2020-07-10 22:48:51 【问题描述】:

我正在学习使用钩子制作应用程序的 React。我一直在关注一个教程,但是我想对其进行一些更改。我有一个包含多个字符串项和一个数组项的对象:

  const [recipe, setRecipe] = useState(
    title: '',
    description: '',
    ingredients: [],
    instructions: '',
    tags: 'none'
  ); 

本教程最初包含所有字符串项,因此以下代码可以完美地更新状态:

    setRecipe( ...recipe, [e.target.name]: e.target.value );
  

所有相似的输入字段之一的示例。

          <input
            type='text'
            placeholder='Title'
            name='title'
            value=title
            onChange=onChange
          />

现在我已将其中一项更改为数组,它不再起作用。我尝试了几种方法,例如:

 const [test, setTest] = useState(
    ingredients: ['bread', 'milk', 'honey']
  );

 const [query, setQuery] = useState('');

  const updateQuery = e => 

    setQuery(e.target.value);
  ;

  const addItem = e => 
    e.preventDefault();

    setTest(test => ( ingredients: [...test.ingredients, query] ));
  ;

return (

          <div>
            <button className='btn btn-light btn-block' onClick=addItem>
              Add ingredient
            </button>
            <input
              type='text'
              placeholder='Description'
              name='ingredients'
              value=ingredients
              onChange=(updateQuery)
            />
          </div>
          <div>
            test.ingredients.map(data => (
              <ul key=data>data</ul>
            ))
          </div>

  );

我正在努力寻找解决方案。

我们将不胜感激。

【问题讨论】:

这一行没有触发你的测试变量已经被声明的错误? setTest(test =&gt; ( ingredients: [...test.ingredients, query] )); 也许用这个例子解释一下你想达到什么目的是件好事? 【参考方案1】:

我看的方式,你需要在addItem中使用useCallback,updateQuery之类的

const updateQuery = useCallback(e => 

    setQuery(e.target.value);
  ,[]);

const addItem = useCallback(e => 
    e.preventDefault();

    setTest(test => ( ingredients: [...test.ingredients, query] ));
  ,[query]);

是hooks原理,想了解这个原理可以搜索Principle of useCallback

如果你想知道简单的方法,我可以告诉你一件事。 在渲染组件时,addItem有查询->状态改变->但是addItem的查询不能改变

【讨论】:

他的问题不在于 memoization,因为重新调用函数相当于有一个没有依赖的 usecallback【参考方案2】:

您提供的代码需要一些格式(又名:onChange=onChange 而不是 onChange 并且您的输入值是 query 而不是成分)

另外,您在编辑旧状态时并没有重新获取它。

我在您的状态中添加了一个非数组整数字段

const [test, setTest] = React.useState(
    nonArray: 0,
    ingredients: ["bread", "milk", "honey"]
  );

然后我将你的 addItem 改成如下所示:

const addItem = e => 
    e.preventDefault();
    setTest(old => ( ...old, ingredients: [...old.ingredients, query] ));
    setQuery("");
  ;

而且它似乎很有效。

请检查这个基本上包含您的代码的working codesandbox。

【讨论】:

【参考方案3】:

问题在于这一行:setTest(test =&gt; ( ingredients: [...test.ingredients, query] )

在使用 react 类组件时,如果不像 this.setState( ingredients: [...test.ingredients, query] ) 那样传播整个先前的状态,就可以设置状态,因为在内部 react 已经将您传递到 this.setState 的新对象与先前的状态合并。

在反应钩子中,React.useState 不会进行合并,因此您必须合并之前的状态,例如 setState(test =&gt; ( ...test, ingredients: [...test.ingredients, query] )

edit:您还在组件顶部声明了变量test。我建议将setTest 中的test 参数重命名为其他名称。

【讨论】:

您在回答之前检查过我的回答吗? ?‍♂️

以上是关于React Hooks 表单处理:使用多个字符串项和一个数组项更新对象的状态的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks 在设置状态的同时处理多个动作的方式是啥?

React Hooks(useEffect) 表单子任务

React-native hooks 表单验证

React Hooks:使用useState更新状态不会立即更新状态[重复]

如何使用 React Hooks 在另一个组件中获取表单的输入值

等待带有 React Hooks 的 Redux Action