如何将API调用结果存入Redux store,组件首次加载时自动调用API
问题解答
1. 接口返回数据后保存到Redux状态
你需要在boardSlice中补全extraReducers配置,用来处理createAsyncThunk生成的异步状态Action:createAsyncThunk执行完成后会自动触发pending(请求中)、fulfilled(请求成功)、rejected(请求失败)三种状态的Action,你只需要在extraReducers中监听成功状态的Action,把返回值赋值给state即可。
修改后的完整boardSlice代码如下:
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'; import { RootState, AppThunk } from '../../app/store'; import { fetchBoard } from './boardAPI'; export interface BoardState { board: any; status: 'idle' | 'loading' | 'failed'; } const initialState: BoardState = { board: {}, status: 'idle', }; export const fetchBoardAsync = createAsyncThunk( 'board/fetchBoard', async (boardId: string) => { const response = await fetchBoard(); console.log('fetch board returned data...' + JSON.stringify(response.data)); return response.data; } ); export const boardSlice = createSlice({ name: 'board', initialState, reducers: { setBoard: (state, action: PayloadAction<any>) => { state.board = action.payload; } }, // 新增extraReducers处理异步Action的返回结果 extraReducers: (builder) => { builder .addCase(fetchBoardAsync.pending, (state) => { state.status = 'loading'; }) .addCase(fetchBoardAsync.fulfilled, (state, action) => { state.status = 'idle'; // 把接口返回的payload赋值给board state.board = action.payload; }) .addCase(fetchBoardAsync.rejected, (state) => { state.status = 'failed'; }); } }); export const { setBoard } = boardSlice.actions; // 状态选择器,你原来的selectBoard可以按这个实现 export const selectBoard = (state: RootState) => state.board.board; export const selectBoardStatus = (state: RootState) => state.board.status; export default boardSlice.reducer;
注意最后要把slice的reducer导出,并且配置到你的store中,这一步如果没做也要补上。
2. 组件首次加载自动触发请求
函数组件中对应类组件componentDidMount生命周期的是依赖数组为空的useEffect Hook,它只会在组件首次挂载完成后执行一次。
修改后的Board组件代码如下:
import React, { useState, useEffect } from 'react'; import { useAppSelector, useAppDispatch } from '../../app/hooks'; import { setBoard, fetchBoardAsync, selectBoard } from './boardSlice'; import styles from './Board.module.css'; export function Board() { const board = useAppSelector(selectBoard); const dispatch = useAppDispatch(); // 新增useEffect,组件挂载自动发起请求 useEffect(() => { dispatch(fetchBoardAsync("")); }, [dispatch]); console.log(JSON.stringify(board)); return ( <div> <div className={styles.row}> <h3>Board</h3> <button className={styles.asyncButton} onClick={() => dispatch(fetchBoardAsync(""))} > Fetch board Data from API </button> </div> </div> ); }
这里把dispatch放到useEffect的依赖数组里即可,Redux的dispatch方法引用是稳定的,不会触发重复执行。
内容的提问来源于stack exchange,提问作者Blankman
相关产品推荐
相关产品推荐

