React投票组件引入useEffect后出现大量重复请求问题求助
问题根源
- 重复请求:你使用的
AnswerContext中active是所有AnswerItem共享的全局状态,每个AnswerItem内的useEffect都依赖了active,只要任意一个投票操作修改了active,所有挂载的AnswerItem都会触发useEffect执行投票请求,最终请求数等于问题数×答案数。 - 投票后不刷新看不到结果:调用
Api.postVote拿到后端返回的最新投票数据后,你没有更新App组件内state.questions对应的答案票数,页面不会自动渲染最新结果。 - 多余的
useEffect:投票是用户主动点击触发的操作,完全不需要通过useEffect监听状态来触发请求,属于不必要的逻辑。
修复步骤
1. 回退AnswerItem逻辑,删除多余useEffect
直接使用你最开始未加useEffect的AnswerItem代码即可,点击投票时直接在事件回调内触发props.onVote即可。
2. 修改App组件,投票成功后更新本地state
在Api.postVote的成功回调中,把后端返回的最新票数更新到本地state,触发页面自动重渲染:
// App.js中修改sendVoteUpsData方法 sendVoteUpsData = (dataV) => { const params = { client_id : this.props.client, the_vote : dataV.vote, the_answerID : dataV.answerID } Api.postVote(params) .then( response => { if(response.data.status === 'success'){ // 假设后端返回的response.data.data包含更新后的answerID、ups、downs字段 const updatedAnswer = response.data.data; this.setState(prevState => ({ questions: prevState.questions.map(question => ({ ...question, answers: question.answers.map(answer => answer.id === updatedAnswer.answerID ? {...answer, ups: updatedAnswer.ups, downs: updatedAnswer.downs} : answer ) })) })) } }) }
3. 优化父组件避免不必要重渲染(可选)
AccordionItem中原来的handleVote每次渲染都会生成新的函数实例,会导致所有AnswerItem不必要重渲染,用useCallback缓存函数即可,同时修正列表key的错误用法(不要用遍历index作为key,要用数据唯一ID):
import React, { useCallback } from 'react'; import AnswerItem from './AnswerItem'; const AccordionItem = (props) => { const handleVote = useCallback((dataV) => { props.voteChanged(dataV) }, [props.voteChanged]) return ( <div> {props.answers.map((data) => ( <AnswerItem key={data.id} index={data.id} ups={data.ups} downs={data.downs} onVote={handleVote} /> ))} </div> ) } export default AccordionItem;
内容的提问来源于stack exchange,提问作者Elichy
相关产品推荐
相关产品推荐

