React useState仅按钮直接调用更新生效,函数内调用不触发重渲染
问题核心原因
- 父组件状态更新函数的写法违反React状态不可变原则,是偶发不触发重渲染的根本原因
- 若
SendMessage为异步函数,未等待执行完成就触发状态更新也可能导致逻辑异常
修复步骤
第一步:修正父组件的changeChatRoomID写法
不要直接给state变量chatRoomIDs赋值,直接将新的id传给状态更新函数即可:
const [chatRoomIDs, setIDofRoom ] = React.useState(0); const changeChatRoomID = (id) => { // 移除对chatRoomIDs的直接赋值操作 setIDofRoom(id); } return ( <div className="container"> <ChatIO chatroomID={chatRoomIDs} chatRoomFunction={changeChatRoomID}/> </div> )
第二步:修正子组件的点击逻辑(如果SendMessage是异步函数)
如果SendMessage是异步请求类方法,需要加async/await等待其执行完成再触发状态更新,避免逻辑冲突:
<Button onClick={() => buttonClick()} variant="contained">senden</Button> // 异步写法 async function buttonClick() { await SendMessage() props.chatRoomFunction(100283100) } // 如果SendMessage是同步方法,保持原有写法即可,父组件修正后就会正常触发重渲染
原理解释
你之前的写法中setIDofRoom(chatRoomIDs = id)会直接修改当前渲染闭包中的state变量值,导致React做状态浅比较时,误以为新状态和旧状态没有差异,就会跳过重渲染,这就是为什么会出现偶发不更新的情况。修正后遵循React状态不可变的规则,状态更新后会正常触发重渲染流程。
内容的提问来源于stack exchange,提问作者innom
相关产品推荐
相关产品推荐

