Redux Toolkit 使用笔记

3,306 阅读1分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

概述

使用Redux ToolKit简化了传统redux创建的流程及代码量;借助createReducercreateSlice这两个钩子函数让我们更轻易的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: {}
});

参考

redux Toolkit官方文档