这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
概述
使用Redux ToolKit简化了传统redux创建的流程及代码量;借助
createReducer
和createSlice
这两个钩子函数让我们更轻易的CRDU全局状态,同时在中间件中默认配置了thunk。
基础依赖包安装
yarn add @reduxjs/toolkit react-redux redux-logger
store
//参考: https://redux-toolkit.js.org/api/configureStore
import { configureStore } from '@reduxjs/toolkit';
import logger from 'redux-logger';
import userReducer from '@src/redux/reducer/users';
import { counterReducer } from './reducer/reducerStandard';
export const store = configureStore({
reducer: {
user: userReducer,
counter:counterReducer
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger)
});
// 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
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from '@src/redux/store'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export const useAppDispatch = () => useDispatch<AppDispatch>()
reducer
/**
* 发起API请求
*/
import { createAsyncThunk, createSlice, createAction, PayloadAction } from '@reduxjs/toolkit';
import { httpsTest } from '@src/api';
export interface User {
value: number;
message: any;
}
export interface Params {
value: number;
key: string;
}
const initialState: User = {
value: 0,
message: 'asd'
};
//定义action
const httpTest = createAction('httpTest');
// First, create the thunk
export const fetchUserById = createAsyncThunk('httpTest', async () => {
const response = httpsTest();
return response;
});
// Then, handle actions in your reducers:
const usersSlice = createSlice({
name: 'users',
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action: PayloadAction<Params>) => {
state.value += action.payload.value;
}
},
// http请求
extraReducers: (builder) => {
builder.addCase(fetchUserById.fulfilled, (state, action: any) => {
state.message = action.payload.message;
});
}
});
export const { increment, decrement, incrementByAmount } = usersSlice.actions;
export default usersSlice.reducer;
app.js入口
// import 'react-native-gesture-handler'; // react navigation的必要配置
import * as React from 'react';
import { Provider } from 'react-redux';
import Home from '@src/pages/index';
import HomeClass from '@pages/class';
import { store } from '@src/redux/store';
// Render the app container component with the provider around it
export default function App() {
return (
<Provider store={store}>
<Home />
{/* <HomeClass /> */}
</Provider>
);
}
用法
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { RootState } from '@src/redux/store';
import { fetchUserById, increment, incrementByAmount } from '@src/redux/reducer/users';
import { useAppDispatch, useAppSelector } from '@src/redux/hooks';
interface AppProps {}
const App = (props: AppProps) => {
const count = useAppSelector((state: RootState) => state.user.value);
const countStandard = useAppSelector((state: RootState) => state.counter.value);
const dispatch = useAppDispatch();
return (
<View style={styles.container}>
<Text>{count}</Text>
<Button
title="按钮"
onPress={() => {
dispatch(incrementByAmount({ value: 1, key: 'sadf' }));
}}
/>
<View style={{ marginTop: 10 }}>
<Button
title="createAsyncThunk"
onPress={() => {
dispatch(fetchUserById());
}}
/>
</View>
<View style={{ marginTop: 10 }}>
<Button
title="createReducer"
onPress={() => {
dispatch(add());
}}
/>
</View>
</View>
);
};
export default App;
const styles = StyleSheet.create({
container: {}
});