【问题标题】:useCallback not updating array with objectuseCallback 不使用对象更新数组
【发布时间】:2023-02-10 03:31:41
【问题描述】:

我正在尝试使用 useCallback 使用对象更新数组,但它不是更新对象,而是添加或附加一个对象。

const items = [
       {
           id: 101,
           name: 'Mae Jemison',
       },
       {
           id: 201,
           name: 'Ellen Ochoa',
       },
   ];
const [headings, setHeadings] = useState(items);

const handleHeadingTextChange = useCallback(
       (value, id) => {
           let items2 = headings;
           items2 = items2.map((item, key) => {
               if (items2[key].id == id) {
                   items2[key].name = value
               }
               return items2
           });

           setHeadings((prevState) => [...prevState, items2]) // adding, not updating
           //setHeadings((prevState) => [...prevState, ...items2]) // try 2 : still adding
       },
       [setHeadings],
   );

<input type="text" id="101" value="" onChange={handleHeadingTextChange} />

所以,改变预期输出是

items = [
        {
            id: 101,
            name: 'Johaan',
        },
        {
            id: 201,
            name: 'Ellen Ochoa',
        },
    ];

但相反,我越来越

items = [
        {
            id: 101,
            name: 'Johaan',
        },
        {
            id: 201,
            name: 'Ellen Ochoa',
        },
       [{
            id: 101,
            name: 'Johaan',
        },
        {
            id: 201,
            name: 'Ellen Ochoa',
        }]
    ];

我不确定如何在 setHeading 函数中设置值,以便它只更新值而不是附加值。有没有办法让它只更新?

【问题讨论】:

  • 我的意思是,你告诉它把自己插入自己。所以它做到了。如果在 Array.map 中返回初始数组,则初始数组现在将是从 Array.map 返回的新数组的值

标签: reactjs react-hooks


【解决方案1】:

问题

  1. .map 遍历整个数组。如果你只是想更新一个,那是没有意义的单身的物品。
  2. onChange需要一个event handler,但是你的回调接受(value, id)

    解决方案

    function MyComponent() {
      const [headings, setHeadings] = useState(items);
    
      const updateName = key => event => {
        setHeadings(prevState => {
          return [
            // elements before the key to update
            ...prevState.slice(0, key),
    
            // the element to update
            { ...prevState[key], name: event.currentTarget.value },
    
            // elements after the key
            ...prevState.slice(key + 1),
          ]
        })
      }
    
      return headings.map((h, key) =>
        <input key={key} id={h.id} value={h.name} onChange={updateName(key)} />
      )
    }
    

    改进

    想象一下,每次您拥有一个具有数组或对象状态的组件时都必须编写该函数。将其提取为通用函数并在必要时使用它 -

    // generic functions
    function arrUpdate(arr, key, func) {
      return [...arr.slice(0, key), func(arr[key]), ...arr.slice(key + 1)]
    }
    
    function objUpdate(obj, key, func) {
      return {...obj, [key]: func(obj[key])}
    }
    
    // simplified component
    function MyComponent() {
      const [headings, setHeadings] = useState(items);
    
      const updateName = key => event => {
        setHeadings(prevState =>
          // update array at key
          updateArr(prevState, key, elem =>
            // update elem name property
            updateObj(elem, "name", prevName =>
              // new element name
              elem.currentTarget.value
            )
          )
        )
      }
    
      return headings.map((h, key) =>
        <input key={key} id={h.id} value={h.name} onChange={updateName(key)} />
      )
    }
    

【讨论】:

    猜你喜欢
    • 2021-12-02
    • 2023-03-04
    • 2021-07-08
    • 1970-01-01
    • 2021-04-29
    • 2023-01-17
    • 1970-01-01
    • 2019-12-15
    • 2017-10-21
    相关资源
    最近更新 更多