使用Redux和Typescript调度API响应

omjgkv6w  于 2023-01-21  发布在  TypeScript
关注(0)|答案(1)|浏览(147)

我非常新的 typescript ,我试图使用Redux与它,我完全失去了,似乎不能理解Redux文件。
我尝试获取数据并将它们分派到Reducer中,以便以后能够像使用Typescript之前那样使用它们,但现在我的方法不是这样工作的:

import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import axios from 'axios';
import { useAppDispatch } from './hooks';

export interface MealState {
  meal:string[],
  input: string,
  favorites: string[],
  categories: string[],
}

const initialState: MealState = {
  meal:[],
  input: '',
  favorites: [],
  categories: [],
};

const mealReducer = createSlice({
  name: 'meal',
  initialState,
  reducers: {

     // GET ALL MEAL
     getAllMeal: (state, action: PayloadAction<string[]>) => {
      console.log('Do something') //<== trying to at least do this
      state.meal = action.payload;
    },

     // ADD INPUT
     addInput: (state, action: PayloadAction<string>)=> {
      state.input = action.payload
    }, 
  }
});

// ----------------------------------------------------------------------

export default mealReducer.reducer

// Actions
export const {
  addInput,
} = mealReducer.actions;


export const getMeal = createAsyncThunk(
  'meal/getMeal',
  async (search: string) => {
    const response: string[] = await axios.get(`https://www.themealdb.com/api/json/v1/1/search.php?s=${search}`);    
    console.log(response);
    const dispatch = useAppDispatch();
    dispatch(mealReducer.actions.getAllMeal(response));    
  }
);

下面是我的代码来触发它(我确实得到了API响应,只是不能分派它)

import { useEffect, useState } from 'react';
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import { getMeal, addInput } from '../redux/meal';
import { RootState } from '../redux/store';
import {getCategories} from '../api/api'

const Header = () => {

  const dispatch = useAppDispatch();

  const input = useAppSelector((state: RootState) => state.meal.input)

  const [inputText, setInputText] = useState(input);

  const inputHandler = (e: { target: { value: string; }; }) => {
    setInputText(e.target.value.toLowerCase());
  };

  useEffect(() => {
    dispatch(getMeal(inputText));
    dispatch(addInput(inputText))
  }, [dispatch, inputText]);

  return (
    <Box sx={{ m: 3 }}>
        <TextField
          onChange={inputHandler}
          placeholder="Search"
          sx={{ mb: 3 }}
        />
    </Box>
  );
}

export default Header
uqjltbpv

uqjltbpv1#

这里的问题与TypeScript无关,问题在于thunk,具体来说,就是useAppDispatch()调用。

export const getMeal = createAsyncThunk(
  'meal/getMeal',
  async (search: string) => {
    const response: string[] = await axios.get(`https://www.themealdb.com/api/json/v1/1/search.php?s=${search}`);    
    console.log(response);
>>  const dispatch = useAppDispatch();
    dispatch(mealReducer.actions.getAllMeal(response));    
  }
);

不能在thunk操作创建器内部使用React挂接。只能调用React函数组件或其他挂接内部的挂接。(Docs: Rules of Hooks
你不需要在这里访问dispatch,但是如果你需要在createAsyncThunk中使用dispatch,你可以通过你的有效负载创建器函数的参数来访问它。

export const getMeal = createAsyncThunk(
  'meal/getMeal',
  async (search: string, { dispatch }) => {
    const response: string[] = await axios.get(`https://www.themealdb.com/api/json/v1/1/search.php?s=${search}`);    
    console.log(response);
    dispatch(mealReducer.actions.getAllMeal(response));    
  }
);

但是你不应该这样做,因为你会错过createAsyncThunk的要点。一个createAsyncThunk动作已经在完成时调度了一个fulfilled动作。你应该return你的thunk中的响应数据来设置这个自动动作的负载。删除getAllMeal大小写减少器,并改为通过extraReducers响应getMeal.fulfilled动作。
一个二个一个一个

相关问题