React状态对象属性变更后页面未渲染问题求助
React状态更新后页面不渲染的问题
我希望通过增减按钮修改state对象中的amount属性,点击按钮时用console.log查看发现属性值已变化,但页面显示的数字并未更新。请问这是什么原因?我哪里操作有误?
以下是我的代码:
import React, { useState, useEffect } from "react"; import { Button } from "react-bootstrap"; export default function App() { const [data, setData] = useState({}); useEffect(() => { const temp = { id: 1, name: "apple", amount: 10 }; setData(temp); }, []); const handleInc = () => { let temp = data; temp.amount++; console.log("increment", temp.amount); setData(temp); }; const handleDec = () => { let temp = data; temp.amount--; console.log("decrement", temp.amount); setData(temp); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <label>name: {data.name}</label> <br /> <label>amount: {data.amount}</label> <br /> <Button onClick={handleDec}>Reduce</Button> <Button onClick={handleInc}>Increase</Button> </div> ); }
问题原因
你直接修改了React状态对象的引用,违反了React的不可变更新原则。
let temp = data;这行代码并没有创建新对象,只是让temp指向了原state对象的内存地址。修改temp.amount时,其实是直接改动了原state的属性。之后调用setData(temp),因为传入的对象和原state是同一个引用,React会判定状态没变化,自然不会触发组件重新渲染,页面也就不会更新。
修复方案
更新状态时必须创建原对象的副本,保证每次传给setData的是新的对象引用:
方法1:用展开运算符创建新对象
const handleInc = () => { const newData = {...data, amount: data.amount + 1}; console.log("increment", newData.amount); setData(newData); }; const handleDec = () => { const newData = {...data, amount: data.amount - 1}; console.log("decrement", newData.amount); setData(newData); };
方法2:函数式更新(更安全)
如果你的更新逻辑依赖前一次的状态值,推荐用函数式更新,避免闭包导致的状态不一致问题:
const handleInc = () => { setData(prevData => { const newAmount = prevData.amount + 1; console.log("increment", newAmount); return {...prevData, amount: newAmount}; }); }; const handleDec = () => { setData(prevData => { const newAmount = prevData.amount - 1; console.log("decrement", newAmount); return {...prevData, amount: newAmount}; }); };
这两种方式都会生成新的对象引用,React检测到状态变化后,就会触发组件重新渲染,页面上的amount值就能正常更新了。
内容的提问来源于stack exchange,提问作者dapidmini
相关产品推荐
相关产品推荐

