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

如何在Redux中重新调用API加载数据(Hangman游戏场景)

问题解决思路

你当前的代码存在一个核心问题:Redux reducer是纯函数,不能在内部调用异步action(比如getPassword()),直接调用不会触发API请求,因为没有通过dispatch来分发这个action。下面是具体的修正方案:


第一步:修正Reducer中的错误

先把restart reducer里的getPassword()调用移除,让它只负责重置状态:

const HangManSlice = createSlice({
    name: 'hangman',
    initialState,
    reducers: {
        increaseError: (state) => {
            state.misstake += 1
        },
        usedCharts: (state, action) => {
            state.usedChart.push(action.payload)
        },
        restart: (state) => {
            state.misstake = 0
            state.usedChart = []
            // 移除这里的getPassword()调用
        }
    },
    extraReducers: (builder) => {
        builder
            .addCase(getPassword.fulfilled, (state, action) => {
                // API返回的是数组(比如["apple"]),要取第一个元素作为密码
                state.password = action.payload[0];
            })
    }
})

同时修正getPassword的异步逻辑,处理API返回的数组格式:

export const getPassword = createAsyncThunk(
    'hangman/getPassword',
    async (_, thunkAPI) => { // 用_占位不需要的payload参数
        try {
            const resp = await axios(url)
            return resp.data
        } catch(error){
            return thunkAPI.rejectWithValue('api not working');
        }
    }
);

第二步:实现点击按钮重新加载密码

有两种简单的实现方式:

方式一:组件中同时分发两个Action

在你的游戏组件里,给“重新开始”按钮绑定点击事件,同时分发restart和getPassword:

import { useDispatch } from 'react-redux';
import { restart, getPassword } from './hangmanSlice';

function HangmanGame() {
  const dispatch = useDispatch();

  const handleRestart = () => {
    // 先重置状态
    dispatch(restart());
    // 再请求新密码
    dispatch(getPassword());
  };

  return (
    <div>
      {/* 游戏内容 */}
      <button onClick={handleRestart}>重新开始游戏</button>
    </div>
  );
}

方式二:创建整合型Thunk Action

如果希望逻辑更集中,可以创建一个专门的Thunk Action,把重置状态和请求密码整合在一起:

// 在hangmanSlice.js中添加
export const restartGame = () => async (dispatch) => {
  dispatch(restart());
  dispatch(getPassword());
};

然后组件里只需要分发这个整合Action:

import { useDispatch } from 'react-redux';
import { restartGame } from './hangmanSlice';

function HangmanGame() {
  const dispatch = useDispatch();

  return (
    <div>
      {/* 游戏内容 */}
      <button onClick={() => dispatch(restartGame())}>重新开始游戏</button>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:25:48