You need to enable JavaScript to run this app. useReducer修改isLoading状态后依赖的useEffect未触发无输出问题
优惠活动
大模型
产品
解决方案
定价
更多

useReducer修改isLoading状态后依赖的useEffect未触发无输出问题

问题原因

一共存在3处核心问题导致无输出:

  • 拼写错误导致代码直接抛出异常,无法正常运行逻辑
    1. useCurrentRequest hook返回值中引用了未定义的weatherRequestState变量,实际定义的状态变量为requestState
    2. CallingComponent中错误调用了不存在的useCurrentWeather hook,实际导入的hook名为useCurrentRequest
  • 同步连续触发状态更新被React批量合并
    在getData中同步先后触发SEND和RESPONSE类型的action,React会将两次状态更新合并执行,最终isLoading的变化为false → true → false,前后最终值一致,不会触发依赖isLoading的副作用执行。

解决步骤

  1. 修正所有拼写错误
  2. 为状态更新添加异步间隔,避免批量合并(符合真实接口请求的异步场景)

修正后的useCurrentRequest代码

import {useReducer, useCallback, useEffect} from 'react';

export const initialState = {
    isLoading: false,
    data: null,
}

const requestReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'SEND':
            return {...state,
                isLoading: true,
            };
        case 'RESPONSE':
            return {...state,
                isLoading: false,
                data: action.responseData
            };
        default:
            return state;
    }
}

//封装了reducer状态修改逻辑的自定义hook
const useCurrentRequest = () => {

    const [requestState, dispatchRequestActions] = useReducer(requestReducer, initialState);

    useEffect(() => {
        console.log("hook内isLoading:", requestState.isLoading);
    }, [requestState.isLoading]);

    const initializeLoading = useCallback(() => {
        dispatchRequestActions({type: 'SEND'});
    },[dispatchRequestActions]);

    const getRequestResponse = useCallback(() => {
        // 模拟异步接口请求
        setTimeout(() => {
            dispatchRequestActions({type: 'RESPONSE', responseData: {someData:true}});
        }, 300)
    }, [dispatchRequestActions]);

    return {
        initializeLoadingPointer: initializeLoading,
        getRequestResponsePointer: getRequestResponse,
        isLoading: requestState.isLoading,
        data: requestState.data,
    }
}

export default useCurrentRequest;

修正后的CallingComponent代码

import {useEffect} from "react";
import useCurrentRequest from "../hooks/useCurrentRequest";

const CallingComponent = props => {
    const {initializeLoadingPointer, getRequestResponsePointer, isLoading} = useCurrentRequest();

    const getData = () => {
            initializeLoadingPointer();
            getRequestResponsePointer();
    };

    useEffect(() => {
        console.log("组件内isLoading:", isLoading);
    }, [isLoading]);

    return (<button onClick={getData}>Get data</button>) 
}

修正后点击按钮会依次打印true、false,符合预期。

内容的提问来源于stack exchange,提问作者David Galvis Sandoval

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 11:57:02