使用Redux-Toolkit使用React Native Typescript像API一样进行异步调用

6uxekuva  于 2023-04-21  发布在  React
关注(0)|答案(1)|浏览(121)

我是使用redux-toolkit进行React Native开发的新手,并试图在按钮上调用API。我使用RN v0.71,但出现错误
Blockquote“类型”AsyncThunkAction〈any,void,AsyncThunkConfig〉“的参数不可分配给类型”AnyAction“的参数。“
请找到下面的代码:

// store.ts

         import { configureStore } from "@reduxjs/toolkit";
         import todoReducer from "../slices/todo/todoSlice"

         export const store = configureStore({
              reducer : {
                todos : todoReducer,
             }
          })

           // Infer the `RootState` and `AppDispatch` types from the store itself
             export type RootState = ReturnType<typeof store.getState>
           // Inferred type: {posts: PostsState, comments: CommentsState, users:UsersState}                  
              export type AppDispatch = typeof store.dispatch

  //hooks.ts
        import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-     redux'
         import type { RootState, AppDispatch } from '../store/store'

       // Use throughout your app instead of plain `useDispatch` and `useSelector`
       export const useAppDispatch: () => AppDispatch = useDispatch
       export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

 ///App.ts

          import { Provider } from "react-redux";
          import { store } from "./src/store/store";
          import Splash from "./src/views/splash/splash";
          import {NavigationContainer} from '@react-navigation/native';
          import { createNativeStackNavigator } from '@react-navigation/native-stack';
          import { Home } from "./src/views/home/home";

        const Stack = createNativeStackNavigator();
        const App = () => {

           return (
        <Provider store = {store}>
        <NavigationContainer>
       <Stack.Navigator>
       <Stack.Screen name="Splash" component={Splash} 
       options={{headerShown: false}} />
        </Stack.Navigator> 
        </NavigationContainer>
        </Provider>
         )

         }

     export default App;



  ///          todoSlice.ts


               import {Todo} from "../../models/todo"
               import { RootState } from "../../store/store";
               import { createSlice } from "@reduxjs/toolkit";
               import { fetchTodos } from "../../actions/fetchTodos";

                type TodosState = {
               // In `status` we will watch
               // if todos are being loaded.
                status: "loading" | "idle";

             // `error` will contain an error message.
               error: string | null;
               list: Todo[];
              };

             const initialState: TodosState = {
                    list: [],
                    error: null,
                    status: "idle",
              };

      export const selectStatus = (state: RootState) =>
     state.todos.status;

     export const todosSlice = createSlice({
name: "todos",
initialState,
reducers: {
  // ...
},

// In `extraReducers` we declare 
// all the actions:
extraReducers: (builder) => {

  // When we send a request,
  // `fetchTodos.pending` is being fired:
  builder.addCase(fetchTodos.pending, (state) => {
    // At that moment,
    // we change status to `loading` 
    // and clear all the previous errors:
    state.status = "loading";
    state.error = null;
  });

  // When a server responses with the data,
  // `fetchTodos.fulfilled` is fired:
  builder.addCase(fetchTodos.fulfilled, 
    (state, { payload }) => {
    // We add all the new todos into the state
    // and change `status` back to `idle`:
    state.list.push(...payload);
    state.status = "idle";
  });

  // When a server responses with an error:
  builder.addCase(fetchTodos.rejected, 
    (state, { payload }) => {
    // We show the error message
    // and change `status` back to `idle` again.
    if (payload) state.error = payload.message;
    state.status = "idle";
     });
    },
  });

   export default todosSlice.reducer

   /// splash.tsx

       import React from "react";
       import { View, TouchableOpacity, Text, SafeAreaView, Image } from "react-native";
       import { styles } from "../../utility/styles/styles";
       import { selectStatus } from "../../slices/todo/todoSlice";
       import { useSelector, useDispatch } from "react-redux";
       import { getHomeData } from "../../actions/get_home_json";



     function Splash({ navigation} : {navigation : any}) {

        const status = useSelector(selectStatus);
        const dispatch = useDispatch();
        const handleClick = () => {dispatch(getHomeData())};


         return (
          <SafeAreaView>
  
          <View >
    
         <Image source={require('../../resources/images/gif/splash.gif')}
         style={styles.image}
         />
  
       <TouchableOpacity style={styles.button} onPress={ () => handleClick()}>
       <Text> Push Home</Text>
        </TouchableOpacity>
 
       </View>
     </SafeAreaView>
    
     );
};

export default Splash;

///UPDATE://GetHomeData

import { createAsyncThunk } from "@reduxjs/toolkit";
    import configAEM from "../service/configAEM"
    import API from "../service/core/api";
   import { Alert } from "react-native";


    export const getHomeData =    createAsyncThunk('actions/getHomeData', async () =>{

const response = await API.get(configAEM.apis.home)
// Get the JSON from the response:
const data = await response.json();

// Return result:
return data;
})

Getting Error on this Line ---> {dispatch(getHomeData())};

我不明白我做错了什么。我遇到了在Typescript createAsynThunk函数没有得到类型的thunk需要调度,所以使用TypedUseSelectorHook和AppDispatch,然后在这种情况下得到了另一个错误,即
无效的钩子调用。钩子只能在函数组件的主体内部调用

zzlelutf

zzlelutf1#

更新:

我终于发现哪里出错了:
而不是const dispatch = useDispatch();,它应该是const dispatch = useAppDispatch();然后我就可以分派任何类型的异步程序

相关问题