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

React useState声明后代码不执行问题排查求助

问题根源:非法调用React Hooks

你在Redux Toolkit的createAsyncThunk异步回调函数里调用了useAxios这个自定义React Hook,这直接违反了React Hooks的核心规则,导致代码执行中断,所以useState声明后的console.log无法运行。

为什么会出现这个现象?

React对Hooks的调用有严格限制:

  • 只能在函数组件的顶层或自定义Hook的顶层调用Hooks
  • 绝对不能在普通函数、异步函数、条件判断、循环中调用Hooks

当React检测到Hooks在非法位置被调用时,会直接终止后续代码的执行,这就是你看到above useState能输出,below useState没输出的原因——useState的调用触发了React的错误拦截,后续代码根本没机会运行。


解决方案

方案一:把useAxios改成普通异步工具函数

既然createAsyncThunk本身就是用来处理异步请求的,没必要用Hook封装请求逻辑,直接改成普通函数即可:

// 修改后的useAxios(改成普通函数,重命名为fetchAxios)
import config from "../config";
import axios from "axios";

axios.defaults.baseURL = config.backendUrl;

export const fetchAxios = async (axiosParams) => {
  const { method, url, requestConfig = {} } = axiosParams;
  const controller = new AbortController();

  try {
    const res = await axios[method.toLowerCase()](url, {
      ...requestConfig,
      signal: controller.signal,
    });
    return { data: res.data, error: null };
  } catch (err) {
    return { data: [], error: err.message };
  }
};

然后在createAsyncThunk里调用这个函数:

export const fetchProducts = createAsyncThunk(
  "products/fetchProducts",
  async (queryParams, { rejectWithValue }) => {
    const { data, error } = await fetchAxios({
      method: "GET",
      url: `/get-product-list?${queryParams}`,
    });

    if (error) {
      return rejectWithValue(error);
    }

    return data; 
  }
);

方案二:在组件中使用useAxios,再同步Redux状态

如果想保留useAxios作为Hook的功能(比如管理组件内的loading/error状态),就必须在React组件里调用它,再通过dispatch更新Redux:

  1. 先给productSlice添加手动更新状态的reducers:
const productSlice = createSlice({
  name: "products",
  initialState,
  reducers: {
    updateProducts: (state, action) => {
      state.products = action.payload;
    },
    updateLoading: (state, action) => {
      state.loading = action.payload;
    },
    updateError: (state, action) => {
      state.error = action.payload;
    },
  },
  // 保留原有的extraReducers...
});

export const { updateProducts, updateLoading, updateError } = productSlice.actions;
  1. 在组件中调用useAxios并同步Redux:
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useAxios } from '../CustomHook/useAxios';
import { updateProducts, updateLoading, updateError } from './productSlice';

const ProductList = ({ queryParams }) => {
  const dispatch = useDispatch();
  const [response, error, loading] = useAxios({
    method: "GET",
    url: `/get-product-list?${queryParams}`,
  });

  useEffect(() => {
    if (loading === "fullfilled") {
      dispatch(updateProducts(response));
      dispatch(updateLoading("fulfilled"));
    } else if (loading === "rejected") {
      dispatch(updateError(error));
      dispatch(updateLoading("rejected"));
    } else {
      dispatch(updateLoading("pending"));
    }
  }, [response, error, loading, dispatch]);

  // 组件渲染逻辑...
};

排查思路总结

  1. 检查Hook调用位置:永远牢记React Hooks的两条规则,只要不在组件/自定义Hook顶层调用,必然出问题
  2. 查看控制台警告:React会在控制台的Warnings标签里提示Invalid hook call,这是最直接的错误线索
  3. 区分Hook和工具函数:如果只是封装请求逻辑,用普通函数;如果需要管理组件状态,才用Hook,且必须在合法位置调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:20:26