【发布时间】:2021-04-07 01:56:33
【问题描述】:
我目前正在尝试学习一些 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
Counter.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 不太熟悉。
任何指针或任何形式的帮助将不胜感激。
【问题讨论】:
标签: reactjs typescript react-native redux redux-thunk