rudex/react-redux和@reduxjs-toolkit基本用法

738 阅读2分钟

基本使用

react-redux

安装

npm install react-redux redux

Store

创建store

import { createStore } from 'redux';
import { reducer } from './reducer';
const store = createStore(reducer)

State / Reducer

const { INCREMENT, DECREMENT } from './constant.js'
const initalState = {
  count: 0,
}

export const reducer = (state = initalState ,action) => {
  switch (action.type) {
    case INCREMENT:
      return state + action.data
    case DECREMENT:
      return state - action.data
    default:
      return state;
  }
}

constant

export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

Action

import { INCREMENT, DECREMENT } from '../../constant/counter'
export const add = data => ({ type: INCREMENT, data })
export const jian = data => ({ type: DECREMENT, data })

Connect

import { connect } from 'react-redux';
import { add, jian } from '../action'

function Counter(props) {
    const { count, add } = props
    return <div>
        <button onClick={() => add()}>+</button>
        <span>{count}</span>
        <button>-</button>
    </div>
}

const mapStateToProps = state => ({
    count: state.count,
});

const mapDispatchToProps = (dispatch) => {
    add: (params) => dispatch(add(params)),
    jian: (params) => dispatch(jian(params)),
};

export default connect(mapDispatchToProps, mapDispatchToProps)(Counter);

个人感觉react-redux 使用流程太过复杂了。

redux原理

// 第一个参数为总体reducer
// 第二个参数为初始state
export function createStore (reducer, initState) {
    // 整个state 形成了闭包
    let currentState = initState
    // 发布订阅的队列
    let subscribes = []
    
    // 获取最新的state
    function getState() {
        return currentState
    }
    
    // 分发 -- 分发以前调用action获取最新的state 然后消费su队列bscribes
    function dispatch(action) {
        currentState = reducer(currentState, action)
        subscribes.forEach(fn => fn())
    }
    
    // 订阅要处理的事情
    function subscribe (fn) {
        subscribes.push(fn);
    }

    return {
        getState,
        dispatch,
        subscribe,
    }
}

这是一个简单的redux原理实现

Redux-toolkit使用

安装

npm install @reduxjs/toolkit

创建切片slice

import { createSlice } from '@reduxjs/toolkit';

// 初始化的state
const initialState = {
    count: 0,
}

export const counterSlice = createSlice({
    name: 'counter', // 唯一的名字
    initialState,
    reducers: {
        increment: (state) => {
            state.count += 1
        },
        decrement: (state) => {
            state.count -= 1
        },
    },
})

// dispatch 使用
export const { increment, decrement } = counterSlice.actions

// 注册到store中
export default counterSlice.reducer

创建store

import { configureStore } from '@reduxjs/toolkit'
import counterReducres from './slice/counter'

export const store = configureStore({
    reducer: {
        counter: counterReducres, // 注册reducer
    }
})

把store 注入到全局

import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './components/Counter';
import { Provider } from 'react-redux';

import { store } from './toolkit'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}><Counter /></Provider>,
);

组件中使用

import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from '../toolkit/slice/counter'

function Counter() {
    const count = useSelector(state => state.counter.count)
    const dispatch = useDispatch()
    return <div>
        <button onClick={() => dispatch(increment())}>+</button>
        <span>{count}</span>
        <button onClick={() => dispatch(decrement())}>-</button>
    </div>
}

export default Counter;

使用react-redux中的hook 结合使用useSelector,useDispatch。useSelector来获取对应的state,useDispatch获取dispatch

总结: redux-toolkit使用中,其他步骤都是固定的。唯一根据业务扩展的是:根据模块自定义切片slice。然后根据把切片导出的reducer注入到store中即可。 感觉相比以前流程还是简单一些。

扩展:

中间件的使用

import { configureStore } from '@reduxjs/toolkit'
import counterReducres from './slice/counter'
import logger from 'redux-logger'

export const store = configureStore({
    reducer: {
        counter: counterReducres,
    },
    middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger)
})

注意⚠️:@reduxjs/toolkit 包以及弃用getDefaultMiddleware方法。middleware为方法参数为一个方法来concat中间件

React-redux

接下来探讨一下react-redux 的原理