Reactjs Can';难道我们就不能改变状态吗。。?副作用是什么。。?

Reactjs Can';难道我们就不能改变状态吗。。?副作用是什么。。?,reactjs,react-dom,Reactjs,React Dom,根据上的建议,我们建议通过以下方法进行功能更新: 函数计数器({initialCount}){ const[count,setCount]=useState(initialCount); 返回( 计数:{Count} setCount(initialCount)}>重置 setCount(prevCount=>prevCount-1)}>- setCount(prevCount=>prevCount+1)}>+ ); } 这是一个相当低级的示例,所以我们主要面临的情况是,我们应该将复杂状态传递

根据上的建议,我们建议通过以下方法进行功能更新:

函数计数器({initialCount}){
const[count,setCount]=useState(initialCount);
返回(
计数:{Count}
setCount(initialCount)}>重置
setCount(prevCount=>prevCount-1)}>-
setCount(prevCount=>prevCount+1)}>+
);
}
这是一个相当低级的示例,所以我们主要面临的情况是,我们应该将复杂状态传递给组件,在这种情况下,下面的方法非常有效:

导出默认函数App(){
const[state,setState]=useState({number:10});
返回(
你好,代码沙盒
{
设置状态((状态)=>{
state.number++;//+不过我很担心这种突变。
返回{…状态};
});
}}
>
{state.number}
);
}
可工作性证明:我的代码的代码SANBDOX链接

但人们通常不会看到用react更新OSS中的状态,为什么会这样

如果使用这种形式的更新会导致任何不良的副作用,有人能帮助我吗?如果有,请提供这样一个codesandbox实例来复制这种行为


谢谢。

下面是一个示例,说明您的代码不起作用,导致意外结果。对于复杂状态,请确保对其进行深度克隆。 这里是链接

导入“/styles.css”; 从“react”导入{useState}; 导出默认函数App(){ const[state,setState]=useState({number:10,arr:[]}); 返回( 你好,代码沙盒 { 设置状态((状态)=>{ state.number++; 状态arr.push(1); 返回{…状态}; /* 我的解决方案:深度克隆状态 const clone=JSON.parse(JSON.stringify(state)); clone.number++; 克隆arr.push(1); console.log(克隆); 返回{…克隆}; */ }); }} > {state.number} ); } 您可以尝试:

import React from 'react';
import ReactDOM from 'react-dom';

function App({initialCount}) {
  const [count, setCount] = React.useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => ({ prevCount: prevCount - 1}))}>-</button>
      <button onClick={() => setCount(prevCount => ({ prevCount: prevCount + 1}))}>+</button>
    </>
  );
}

export default App;


ReactDOM.render(
  <React.StrictMode>
    <App initialCount={{ number: 10 }}/>
  </React.StrictMode>,
  document.getElementById('root')
);
从“React”导入React;
从“react dom”导入react dom;
函数App({initialCount}){
const[count,setCount]=React.useState(initialCount);
返回(
计数:{Count}
setCount(initialCount)}>重置
setCount(prevCount=>({prevCount:prevCount-1}))}>-
setCount(prevCount=>({prevCount:prevCount+1}))}>+
);
}
导出默认应用程序;
ReactDOM.render(
,
document.getElementById('root'))
);

虽然您的示例有效,但它并不是编写东西的完美且最无bug的方式

代码工作的原因是,您正在浅层克隆状态并返回它,从而导致
对象。is
检入响应失败并重新呈现组件还要注意,spread语法只对对象进行一级克隆

当您更新上述嵌套变量,然后作为道具传递给其他组件,这些组件随后扩展PureComponent或使用
React.meemo
在重新渲染时进行优化时,就会出现问题

例如:

const SomeComp=memo((道具)=>{
返回{props.nestedKey.id};
});
导出默认函数App(){
const[state,setState]=useState({number:10,嵌套:{id:1});
返回(
你好,代码沙盒
{
设置状态((状态)=>{
state.number++;
state.nested.id++;
返回{…状态};
});
}}
>
{state.number}
);
}
如果您查看上面的代码,即使id值是updates,SomeComp也不会重新渲染以更新其值

更新状态的正确方法如下

export default function App() {
  const [state, setState] = useState({ number: 10 });
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button
        onClick={() => {
          setState((state) => {
            return { ...state, number: state.number + 1 };
          });
        }}
      >
        {state.number}
      </button>
    </div>
  );
}
导出默认函数App(){
const[state,setState]=useState({number:10});
返回(
你好,代码沙盒
{
设置状态((状态)=>{
返回{…状态,编号:state.number+1};
});
}}
>
{state.number}
);
}

在您的示例中,您没有违反任何经验法则。您可以更改以前的状态并设置更改状态的副本。那没关系。在onClick中,如果您在没有setState的情况下执行了
state.number++
,那么您的组件将不会更新用于响应的tasks。。!不要直接改变你的状态谢谢你的回应。。!如果您禁用StrictMode,它工作得很好,请检查这里:您说什么…?感谢您的回复。。!太棒了,感谢mak我的案子失败了,我感谢你的帮助和花时间来帮助我。谢谢!!
const SomeComp = memo((props) => {
  return <span>{props.nestedKey.id}</span>;
});
export default function App() {
  const [state, setState] = useState({ number: 10, nested: { id: 1 } });
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button
        onClick={() => {
          setState((state) => {
            state.number++;
            state.nested.id++;
            return { ...state };
          });
        }}
      >
        {state.number}
        <SomeComp nestedKey={state.nested} />
      </button>
    </div>
  );
}
export default function App() {
  const [state, setState] = useState({ number: 10 });
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button
        onClick={() => {
          setState((state) => {
            return { ...state, number: state.number + 1 };
          });
        }}
      >
        {state.number}
      </button>
    </div>
  );
}