Reactjs 反应使用效果不点火,布局不';不变

Reactjs 反应使用效果不点火,布局不';不变,reactjs,react-native,use-effect,use-state,Reactjs,React Native,Use Effect,Use State,伙计们 我试图更改数组并将其传递给useState函数。问题是,当我将修改后的数组作为参数传递给useState时,DOM不会捕捉到更改,useEffect也不会 有一种方法可以重现问题: import React, { useEffect, useState } from "react"; export default function App() { const [mark, setMark] = useState([]); function ChangeVa

伙计们

我试图更改数组并将其传递给useState函数。问题是,当我将修改后的数组作为参数传递给useState时,DOM不会捕捉到更改,useEffect也不会

有一种方法可以重现问题:

import React, { useEffect, useState } from "react";

export default function App() {
  const [mark, setMark] = useState([]);

  function ChangeValue() {
    const arr = mark;
    arr.push("hello");
    console.log(arr);
    setMark((mark) => {
      return arr;
    });
  }

  useEffect(() => {
    console.log("ADDED VALUE");
  }, [mark]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {mark.map((item) => {
        return <h3>{item}</h3>;
      })}
      <button onClick={() => ChangeValue()}>Add More</button>
    </div>
  );
}
import React,{useffect,useState}来自“React”;
导出默认函数App(){
const[mark,setMark]=useState([]);
函数ChangeValue(){
const arr=标记;
arr.push(“你好”);
控制台日志(arr);
设置标记((标记)=>{
返回arr;
});
}
useffect(()=>{
控制台日志(“附加值”);
},[马克];
返回(
你好,代码沙盒
{mark.map((项目)=>{
返回{item};
})}
ChangeValue()}>添加更多
);
}
上面的代码有一个沙箱:


如您所见,该函数始终正确记录新状态,但useEffect不会启动,DOM也不会更改。

您可以更改状态,而是在React重新呈现组件时创建一个副本,该副本基于与以前状态的浅层比较(
===
)(有关详细信息,请阅读文档)

此外,在渲染组件阵列时,还应指定:

export default function App() {
  const [mark, setMark] = useState([]);

  function changeValue() {
    setMark((mark) => [...mark, "hello"]);
  }

  useEffect(() => {
    console.log("ADDED VALUE");
  }, [mark]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {mark.map((item, index) => {
        return <h3 key={index}>{item}</h3>;
      })}

      <button onClick={changeValue}>Add More</button>
    </div>
  );
}
导出默认函数App(){
const[mark,setMark]=useState([]);
函数changeValue(){
设置标记((标记)=>[…标记,“你好”]);
}
useffect(()=>{
控制台日志(“附加值”);
},[马克];
返回(
你好,代码沙盒
{mark.map((项目,索引)=>{
返回{item};
})}
添加更多
);
}

只要使用

const arr = [...mark]
而不是

const arr = mark

因为当您只执行
const arr=mark
时,它不会创建新数组,而是创建对同一数组的新引用。当您执行
const arr=[…mark]
时,它每次都会使用mark数组中的元素创建一个新数组。

这类似于@Dennis Vash的答案,但更短,可能更接近真实场景(因为您可能希望向mark数组添加动态值)

export default function App() {
    const [mark, setMark] = useState([]);

    useEffect(() => {
        console.log('ADDED VALUE');
    }, [mark]);

    return (
        <div className="App">
            <h1>Hello CodeSandbox</h1>
            {mark.map((item, index) => {
                return <h3 key={index}>{item}</h3>;
            })}
            <button onClick={(event) => setMark([...mark, event.target.value])}>Add More</button>
        </div>
    );
}
导出默认函数App(){
const[mark,setMark]=useState([]);
useffect(()=>{
console.log(“增值”);
},[马克];
返回(
你好,代码沙盒
{mark.map((项目,索引)=>{
返回{item};
})}
setMark([…mark,event.target.value])}>添加更多
);
}