React中onClick触发方法内调用setState实现投票状态更新的问题
解决方案
你的代码存在两个核心问题需要调整:
- voteHandler方法没有接收投票类型的入参,无法区分用户点击的是Yes还是No按钮
- React的
setState是异步批量更新的,调用setVote后立刻读取vote变量,拿到的是更新前的旧值,直接传给父组件会出现数据错误
完整修改后的代码
import React, { useState, useContext } from 'react'; import {AnswerContext} from './AnswerWrapper'; const AnswerItem = (props) => { // 原indexCount相关逻辑未被使用,可直接删除 const { active, setActive } = useContext(AnswerContext) const [vote, setVote] = useState(); // 新增第三个参数voteType接收投票类型 const voteHandler = (e, index, voteType) => { e.preventDefault(); setActive(index); // 更新本地state setVote(voteType); // 直接用入参的voteType传给父组件,避开state异步更新的问题 props.onVote ({ vote : voteType, answerID : index }) } return ( <div> {/* 点击Yes传up */} <button onClick={(e) => voteHandler(e, props.index, 'up')}>Yes <span>({props.ups ?? 0})</span></button> {/* 点击No传down */} <button onClick={(e) => voteHandler(e, props.index, 'down')}>No <span>({props.downs ?? 0})</span></button> </div> ) } export default AnswerItem;
补充说明
如果你确实需要在vote状态更新完成后再执行其他逻辑,可以把传给父组件的逻辑放到useEffect中监听vote变化触发:
useEffect(() => { if(vote) { props.onVote({ vote, answerID: active }) } }, [vote, active, props.onVote])
这种场景下voteHandler里就不需要写传给父组件的逻辑,只需要更新setVote和setActive即可。
内容的提问来源于stack exchange,提问作者Elichy
相关产品推荐
相关产品推荐

