You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Linter提示的依赖后出现React无限重渲染循环,如何解决并消除警告?

解决React useEffect依赖警告与无限循环问题

原组件代码

import { React, useState, useEffect } from "react";
import QuestionContext from "./QuestionContext";
import questions from "../data/questions.json";
import { useNavigate } from "react-router-dom";

const SectionState = (props) => {
    // set questions from json to an array of 4 elements
    const newQuestions = Object.keys(questions.content).map(
        (key) => questions.content[key].question
    );
    //useState for Question state
    const [currentQuestion, setCurrentQuestion] = useState(0);
    const newQuestionsArr = {
        qID: 0,
        questionTxt: newQuestions[currentQuestion],
    }
    const [questionCtx, setQuestionCtx] = useState(newQuestionsArr);
    const navigate = useNavigate()

    useEffect(() => {
        setQuestionCtx(prevState => ({
            ...prevState,
            qID: currentQuestion,
            questionTxt: newQuestions[currentQuestion],
         }));
    }, [currentQuestion]);

    const updateNextQuestion = () => {
        if (!(currentQuestion >= newQuestions.length)) {
            setCurrentQuestion((nextCurrentQuestion) => nextCurrentQuestion + 1);
        }
        else{
            navigate('/result')
        }
    };

    const updatePrevQuestion = () => {
        if (currentQuestion <= 0) {
            console.log(`No more questions`);
        } else {
            setCurrentQuestion((prevCurrentQuestion) => prevCurrentQuestion - 1);
        }
    };

    return (
        <QuestionContext.Provider
            value={{ questionCtx, updateNextQuestion, updatePrevQuestion }}>
            {props.children}
        </QuestionContext.Provider>
    );
};

export default SectionState;

Linter警告

React Hook useEffect has a missing dependency: 'newQuestions'. Either include it or remove the dependency array

问题分析

newQuestions是每次组件渲染时都会重新创建的数组,即使内容未变,引用地址也会更新。如果把它加入useEffect的依赖数组,会触发useEffect重复执行,进而更新questionCtx导致组件重渲染,形成无限循环。

解决方案

方案一:用useMemo缓存newQuestions

通过useMemo缓存数组,只有当依赖的questions发生变化时才重新生成(导入的JSON文件是静态资源,不会变化,所以newQuestions只会创建一次):

import { React, useState, useEffect, useMemo } from "react";
// ...其他导入不变

const SectionState = (props) => {
    // 用useMemo缓存newQuestions
    const newQuestions = useMemo(() => {
        return Object.keys(questions.content).map(
            (key) => questions.content[key].question
        );
    }, [questions]);

    const [currentQuestion, setCurrentQuestion] = useState(0);
    const [questionCtx, setQuestionCtx] = useState({
        qID: 0,
        questionTxt: newQuestions[0],
    });
    const navigate = useNavigate()

    useEffect(() => {
        setQuestionCtx(prevState => ({
            ...prevState,
            qID: currentQuestion,
            questionTxt: newQuestions[currentQuestion],
         }));
    }, [currentQuestion, newQuestions]); // 安全加入newQuestions到依赖

    // ...updateNextQuestion、updatePrevQuestion和return部分不变
};

方案二:移除questionCtx状态,直接计算上下文值(更优)

questionCtx完全可以通过currentQuestion和newQuestions实时计算,不需要单独维护state,从根源消除useEffect和依赖问题:

import { React, useState, useMemo } from "react";
// ...其他导入不变

const SectionState = (props) => {
    const newQuestions = useMemo(() => {
        return Object.keys(questions.content).map(
            (key) => questions.content[key].question
        );
    }, [questions]);

    const [currentQuestion, setCurrentQuestion] = useState(0);
    const navigate = useNavigate()

    // 直接计算questionCtx,无需state和useEffect
    const questionCtx = {
        qID: currentQuestion,
        questionTxt: newQuestions[currentQuestion],
    };

    const updateNextQuestion = () => {
        if (!(currentQuestion >= newQuestions.length)) {
            setCurrentQuestion((nextCurrentQuestion) => nextCurrentQuestion + 1);
        } else {
            navigate('/result')
        }
    };

    const updatePrevQuestion = () => {
        if (currentQuestion <= 0) {
            console.log(`No more questions`);
        } else {
            setCurrentQuestion((prevCurrentQuestion) => prevCurrentQuestion - 1);
        }
    };

    return (
        <QuestionContext.Provider
            value={{ questionCtx, updateNextQuestion, updatePrevQuestion }}>
            {props.children}
        </QuestionContext.Provider>
    );
};

export default SectionState;

说明

方案二更简洁高效,避免了额外的state更新和useEffect执行,直接通过当前状态计算上下文值,同时用useMemo确保newQuestions不会重复创建,彻底消除了linter警告和无限循环风险。

内容的提问来源于stack exchange,提问作者dartHTh0t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:15:45