如何在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
相关产品推荐
相关产品推荐

