React组件间共享数据遇activeState只读错误,求修改方案
问题分析与修复方案
核心错误原因
- 变量重复声明与初始化错误:App组件中先直接赋值
activeState = {...},又用useState声明同名状态,导致变量冲突;且useState未正确传入初始值。 - 直接修改只读Props:React中Props是只读属性,
active_state.graph_data = data.lst[0]直接修改传入的props,触发"read-only"错误。 - 异步操作时序错误:
fetch是异步执行的,在fetch外部直接访问data.lst[0]时,接口数据还未返回,此时data是组件本地state的初始空数组,会导致取值错误。
修复后的代码
App.js
function App() { // 直接在useState中初始化全局状态,避免重复声明变量 const [activeState, setActiveState] = useState({ graph_data: 0, other_data: 1, }); return ( <div className="App"> <div className="App-body"> <div className="toolbar-element" style={{ top: "50px", left: "0px" }}> <ToolbarElement active_state={activeState} updateState={setActiveState} /> </div> <div className="graph-element" style={{ top: "50px", right: "0px" }}> <GraphElement active_state={activeState} updateState={setActiveState} /> </div> </div> </div> ); } export default App;
ToolbarElement.js
function ToolbarElement({ active_state, updateState }) { const [data, setdata] = useState({ lst: [], }); const handleButtonClick = () => { console.log('Button clicked!'); fetch("/data") .then((res) => res.json()) .then((fetchedData) => { // 先存储接口返回的原始数据到本地state setdata({ lst: fetchedData, }); // 创建新状态对象,通过扩展运算符保留原有字段,仅修改目标属性 const newActiveState = { ...active_state, graph_data: fetchedData[0] }; // 调用父组件方法更新全局状态 updateState(newActiveState); }); }; return ( <div style={{ height: '33.33%', backgroundColor: '#F0F0F0' }}> <button onClick={handleButtonClick}>Click me!</button> </div> ); } export default ToolbarElement;
GraphElement.js
function GraphElement({ active_state, updateState }) { return ( <div style={{ height: '33.33%', backgroundColor: '#E8E8E8' }}> <p>{active_state.graph_data}</p> </div> ); } export default GraphElement;
关键修复点说明
- 状态初始化规范:在
useState中直接传入初始状态对象,删除冗余的变量声明,避免变量冲突。 - 不可变状态更新:通过扩展运算符
...创建新的状态对象,而非直接修改原props或状态对象,符合React的不可变数据原则,避免只读错误。 - 异步逻辑修正:将状态更新逻辑放在
fetch的回调内部,确保接口数据返回后再进行赋值,解决时序错误导致的取值问题。 - 简化回调传递:直接将
setActiveState作为updateState传入子组件,无需额外包装箭头函数,减少代码冗余。
内容的提问来源于stack exchange,提问作者Mich
相关产品推荐
相关产品推荐

