reactjs - 如何使用 createAsyncThunk 帮助程序分派(dispatch) AsyncThunk

标签 reactjs typescript react-native redux redux-thunk

我目前正在尝试学习一些 typescript/redux/reactnative。

我想我已经了解了 redux 如何处理状态管理的基本概念。然而,我现在有点坚持尝试让异步状态管理与 redux thunk 中间件一起使用。

到目前为止,我已经得到了这个简单的反例:

Rootreducer.tsx

import { combineReducers } from "@reduxjs/toolkit";
import { create } from "react-test-renderer";
import { createStore, applyMiddleware } from "redux"
import thunk, {ThunkMiddleware} from "redux-thunk";
import { AppActions } from "../Util/Types";
import counterReducer from "./CounterReducer"
export const rootReducer = combineReducers({
    counter: counterReducer
})
export type AppState = ReturnType<typeof rootReducer>

const middleware = applyMiddleware(thunk as ThunkMiddleware<AppState, AppActions>)
export const store = createStore(rootReducer, middleware)

CounterReducer.tsx:

import { createSlice, PayloadAction, createAsyncThunk } from "@reduxjs/toolkit"
import { CounterState } from "../Util/Types"

const initialState = { num : 0 } as CounterState

function delay(milliseconds: number, count: number): Promise<number> {
    return new Promise<number>(resolve => {
            setTimeout(() => {
                resolve(count);
            }, milliseconds);
        });
    }

export const delayedIncrement = 
    createAsyncThunk (
        "delayedIncrement",
        async(arg : number , thunkAPI) => {
            const response = await delay(5000, 5)
            return response
        }
    )

const counterSlice = createSlice({
    name: "counter",
    initialState,
    reducers: {
        increment(state) {
            state.num++
        },
        decrement(state) {
            state.num--
        },
        incrementByAmount (state, action : PayloadAction<number>) { 
            state.num += action.payload
        }
    },
    extraReducers : {
        [delayedIncrement.fulfilled.type]: (state, action) => {
            state.num += action.payload
        },
        [delayedIncrement.pending.type]: (state, action) => {
            state.num
        }
    }
})

export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer

计数器.tsx:

import { FC, useState } from "react";
import  { Button, Text, View } from "react-native"
import React from "react"
import { connect, ConnectedProps, useDispatch } from "react-redux"
import  { AppState } from "../Reducers/RootReducer" 
import { increment, decrement, incrementByAmount, delayedIncrement} from "../Reducers/CounterReducer";

const mapState = (state : AppState) => ({
    counter: state.counter.num
})
const mapDispatch = {
    increment : () => ({ type: increment }),
    decrement : () => ({ type : decrement }),
    incrementByAmount : (value : number) => ({type: incrementByAmount, payload: 5})
}
const connector = connect(
    mapState,
    mapDispatch
)
type PropsFromRedux = ConnectedProps<typeof connector>
interface CounterProps extends PropsFromRedux  {
    a : string
}
const Counter : FC<CounterProps> = (props) => {
    const dispatch = useDispatch 
    return (
        <View>
            <Text>{props.a}</Text>
            <Text>{props.counter.toString()}</Text>
            <Button title="increment" onPress={props.increment}> </Button>
            <Button title="decrement" onPress={props.decrement}> </Button>
            <Button title="increment5" onPress= {  () => { props.incrementByAmount(5) }}> </Button>
            <Button title="delayed" onPress= {  () => { dispatch (delayedIncrement(5)) }}> </Button>

        </View>
    )
}
export default connector(Counter)

当我尝试像这样调度延迟增量时:

<Button title="delayed" onPress= {  () => { dispatch (delayedIncrement(5)) }}> </Button>

我收到以下错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

我非常仔细地遵循了 redux 提供的文档,所以我不确定为什么我不能让它发挥作用?这个错误本身对我来说没有多大意义,但我一般对 javascript 不太熟悉。

任何类型的指示或帮助将不胜感激。

最佳答案

你的 React 组件是错误的。

你有:

const dispatch = useDispatch

请注意,这只是将 useDispatch Hook 本身指定为 dispatch 函数,这是不正确的。这意味着稍后,当您调用 dispatch() 时,您实际上是在调用 useDispatch()。这会导致钩子(Hook)使用错误。

相反,您需要:

const dispatch = useDispatch();

即,现在调用钩子(Hook),将结果保存为名为dispatch的变量。

关于reactjs - 如何使用 createAsyncThunk 帮助程序分派(dispatch) AsyncThunk,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65509056/

相关文章:

react-native - 未找到名称为 "focus"的命令

react-native - Flow Promise 此类型与 undefined undefined 不兼容

javascript - 输入字段的 onChange 函数不起作用

audio - 选择 React.js 中组件的所有实例

Angular 构造函数参数@optional vs 问号用法

javascript - Typescript/Javascript - 使用 new String() 和 s = '' 声明变量

reactjs - 为什么 mobx-react 观察者会破坏 react-router-dom navlink 事件类?

reactjs - Jest SpyOn 选择正确的重载

javascript - 无法使用 formControl 与共享组件绑定(bind)默认值

ecmascript-6 - react-native init 给出错误 : Couldn't find preset "es2015"