使用 Hooks 在 React 中更新数组

Updating an array in React using Hooks

我正在尝试弄清楚 React Hook 的工作原理 API。我正在尝试向列表中添加一个数字。我评论的代码,即 myArray.push... 似乎没有执行该操作,尽管它下面的代码工作正常。为什么会这样?

import React, {useState} from 'react'

export default () => {

  const [myArray, setArray] = useState([1,2,3])

  return (
    <div>
      {myArray.map((item=>{

        return <li>{item}</li>

      }))}
      <button onClick = {()=>{

        // myArray.push(myArray[myArray.length-1]+1)
        // setArray(myArray)

        setArray([...myArray, myArray[myArray.length-1]+1])

      }}>Add</button>
    </div>
  )
}

您没有在注释代码中改变数组,因此当您尝试设置状态时,挂钩会在内部检查是否正在传递相同的状态,因为引用没有为 myArray 更新,因此不会触发重新-再次渲染。

但是在工作代码中,您正在创建一个新的数组实例,因此更新工作正常

对于比单个值更复杂的情况,我建议使用 useReducer

function App() {
  const [input, setInput] = useState(0);

  const [myArray, dispatch] = useReducer((myArray, { type, value }) => {
    switch (type) {
      case "add":
        return [...myArray, value];
      case "remove":
        return myArray.filter((_, index) => index !== value);
      default:
        return myArray;
    }
  }, [1, 2, 3]);

  return (
    <div>
      <input value={input} onInput={e => setInput(e.target.value)} />
      <button onClick={() => dispatch({ type: "add", value: input})}>
        Add
      </button>

      {myArray.map((item, index) => (
        <div>
          <h2>
            {item}
            <button onClick={() => dispatch({ type: "remove", value: index })}>
              Remove
            </button>
          </h2>
        </div>
      ))}
    </div>
  );
}

您可以使用 way to deep clone an object 并将其用作临时变量来更改数组的值。

这是您的代码示例:

import React, { useState } from 'react'

export default () => {
  const [myArray, setArray] = useState([1, 2, 3])
  var tmpArray = JSON.parse(JSON.stringify(myArray))

  return (
    <div>
      {myArray.map((item) => {
        return <li>{item}</li>
      })}
      <button
        onClick={() => {
          tmpArray.push(tmpArray[tmpArray.length - 1] + 1)
          setArray(tmpArray)
        }}
      >
        Add
      </button>
    </div>
  )
}