如何避免React组件重复渲染?以Dashboard组件为例
解决Dashboard组件因自定义Hook多次渲染的问题
你的Dashboard组件因useAllLPTokens Hook中多次调用setState导致重复渲染,核心原因是多个独立的useState每次更新都会触发一次组件重渲染——当你连续调用setStatus、setResponse、setPayload时,会引发三次额外渲染。以下是具体修改方案:
方案1:合并多个状态为单一对象
将分散的status、loading、error、response、payload合并成一个状态对象,这样一次状态更新只会触发一次渲染:
修改后的useAllLPTokens Hook代码:
const useAllLPTokens = (): GraphQLResponse<LPTokens> => { // 合并所有状态为一个对象 const [state, setState] = useState<{ status: number; loading: boolean; error: any; response: any; payload: LPTokens | undefined; }>({ status: 0, loading: false, error: undefined, response: undefined, payload: undefined }); const getLPTokenData = async () => { // 仅一次更新loading状态 setState(prev => ({ ...prev, loading: true })); try { // 修复axios请求参数:headers需放在第三个config参数中,而非data内 const res = await axios.post(subgraphEndpoint, { query: graphQuery }, { headers: { "Content-Type": "application/json" } } ); // 一次性更新所有成功状态 setState({ status: res.status, loading: false, error: undefined, response: res, payload: res.data }); } catch (error) { // 一次性更新错误状态 setState(prev => ({ ...prev, loading: false, error: error, status: 500 // 可根据实际错误场景调整状态码 })); } }; useEffect(() => { let isMounted = true; const fetchData = async () => { if (!isMounted) return; await getLPTokenData(); }; fetchData(); // 组件卸载时取消后续状态更新,避免内存泄漏 return () => { isMounted = false; }; }, []); return { status: state.status, loading: state.loading, error: state.error, response: state.response, payload: state.payload }; };
额外优化说明
- 修复了原代码中axios请求的参数错误:原代码把
headers放在请求data内,会导致请求格式不符合预期,现已移至第三个参数的配置对象中。 - 添加了组件卸载防护:通过
isMounted标志避免组件卸载后执行状态更新,防止React内存泄漏警告。
原理说明
React中每次调用setState(包括单个useState的更新)都会触发一次组件重渲染。合并状态后,无论请求成功还是失败,都只调用一次setState,将多次渲染合并为一次,从而减少Dashboard组件的渲染次数。
内容的提问来源于stack exchange,提问作者code_learner93
相关产品推荐
相关产品推荐

