如何使用react钩子将新值推入当前数组?

时间:2019-12-21 14:00:09

标签: javascript arrays reactjs react-hooks use-effect

这是源代码。

import React, { useState } from "react"
import ReactDOM from "react-dom"
import "./styles.css"

function App() {
  const [arr, setArr] = useState([1,2,3]) 
  return (
    <div className="App">     
      <h1>        
        Length:{arr.length}      
      </h1>   
      <h2>
        Values:
        {arr.map(i=>i+',')}
      </h2>

      <button
        onClick={() => {
          arr.push(0)    //my wrong code
          setArr(arr)    //my wrong code
          // setArr(prevValues => [...prevValues, 0])//Alex K's answer
          // setArr(prevArr => [...prevArr, prevArr.length + 1]); //rotemls98's answer
          // setArr([...arr,1])//venkateshwar's answer
          console.log(arr);
        }}
      >
        push
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root")
ReactDOM.render(<App />, rootElement)

我要做的是将新值推入当前数组,并在单击按钮时更新长度和值。
它可以正常打印到控制台,但不会更改显示。
如何解决呢? enter image description here

4 个答案:

答案 0 :(得分:2)

如果setState返回之前的相同状态,则

react不会重新呈现。 当您使用push方法时,您会更改状态对象。 而是使用新项目创建一个新数组。

始终以不变的方式更新您的状态。

在您的情况下:

onClick={() => {
   setArr((prevArr) => ([...prevArr, prevArr.length + 1]));
}}

答案 1 :(得分:1)

我不太确定要向数组中推入哪些值,但是问题的根本原因是您要对有状态数组进行突变,然后尝试对其进行更新(第22和23行)。

删除第22行的arr.push(0),然后将第23行替换为:

setArr(prevValues => [...prevValues, 0])

,您将看到实时状态更新。在此示例中,我为每次单击按钮向数组添加了0,您可以将其更改为想要推入数组的任何值。请记住,永远不要改变有状态数组,希望能有所帮助!

答案 2 :(得分:1)

新数组的引用存储在旧数组变量中

const [arr, setArr] = useState([1,2,3])
setArr([...arr,1])

答案 3 :(得分:0)

setArr 应该包含一个箭头函数来访问 prevState,以避免不正确/过时的状态快照,因为 react 调度状态更新,它不会立即执行它们

const [arr, setArr] = useState([1,2,3]);
setArr(prevArr=>{
return [...prevArr,4]
});

如果它是一个对象,并且您想更改单个键的值。

const [userInput, setUserInput] = useState({
        enteredTitle: '',
        enteredAmount: '',
        enteredDate: ''
    });
setUserInput((prevUserInput)=>{
          return {
            ...prevUserInput,
            enteredTitle: "Something Else"
        }
})
//for copying the whole object, and only changing enteredTitle's value in it