Day03 redux 最简使用手册

140 阅读2分钟

react redux

Redux 中文网:www.reduxjs.cn/basics/redu…

redux 最简使用手册

1、安装 redux

(备注:注意版本,react-redux ^8.0.2,@reduxjs/toolkit ^1.8.3 )

# Redux + Plain JS template
npx create-react-app my-app --template redux

# Redux + TypeScript template
npx create-react-app my-app --template redux-typescript

执行成功后,生成 my-app 项目,目录结构如下:(备注:只列举重点目录结构)

- src
-- app
--- store.js
-- todo // todo 文件夹由手动新建
--- Todo.js
--- actions.js
--- todoReducer.js
-- App.js

已有项目中安装 redux:

# If you use npm:
npm install react-redux

# Or if you use Yarn:
yarn add react-redux

2、新建 store 对象。

store 是单一的,一个项目只能创建一个 store 。在设计的时候应该想好如何设计 state 的结构,使得后期方便管理和扩展。比如,每个页面的 state 可以各自独立为一个文件。 在 src/app/store.js 文件中:

import { configureStore } from '@reduxjs/toolkit'

export const store = configureStore({})

3、新建 action 函数。

action 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state 。action 的返回值是个对象,对象中的 type 字段用于描述 action 函数的功能,值类型是字符串,通常用常量表示。对象的其他字段可根据需要自定义。 新建一个页面 /todo , todo 页面中包含自己的 state 。

新建 src/todo/actions.js 文件:

const ADD_TODO = 'ADD_TODO'

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

4、使用 dispatch。

dispatch 通过调用 action 改变 state 的值。也只有 dispatch 能够改变 state 的值。 新建 src/todo/Todo.js 文件:

import { useDispatch } from 'react-redux';
import { addTodo } from "./actions"

const Todo = () => {
  const dispatch = useDispatch()
  dispatch(addTodo('添加 todo'))

  return (
    <div>todo</div>
  )
}

export default Todo

5、新建 reducer 函数。

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。 reducer 是一个纯函数,接收旧的 state 和 action,返回新的 state。

const reducer = function (state, action) {
  // ...
  return new_state
}

我们使用 createSlice 方法,管理不同页面的 reducer 。新建 src/todo/todoReducer.js 文件:

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

export const todoSlice = createSlice({
  name: 'todo',
  initialState: {
    text: 'todo初始值',
    list: []
  },
  reducers: {
    increment: (state) => {
      state.text += 's';
    },
    addItem: (state) => {
      state.list.push(state.text)
    }
  },
})

export const { increment, addItem } = todoSlice.actions

export const todoReducer = (state) => state.todo.text

export const listReducer = (state) => state.todo.list

export default todoSlice.reducer

实际应用中,store.dispatch 方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入 createStore 方法。在 src/app/store.js 文件添加各个页面的 reducer:

import { configureStore } from '@reduxjs/toolkit';
import todoReducer from '../todo/todoReducer';

export const store = configureStore({
  reducer: {
    todo: todoReducer,
  },
});

6、用 store.getState() 获取当前时刻的 state 。

store 对象包含所有数据。如果想得到某个时点的数据,就要对 store 生成快照。这种时点的数据集合,就叫做 state 。 在 src/todo/Todo.js 文件添加代码:

import { useSelector, useDispatch } from 'react-redux';
import { todoReducer, increment, listReducer, addItem } from './todoReducer'

const Todo = () => {
  const dispatch = useDispatch()
  const text = useSelector(todoReducer)
  const list = useSelector(listReducer)

  return (
    <>
      <div>
        {
          [list].map((item, index) => {
            return (
              <div key={index}>{item}</div>
            )
          })
        }
      </div>
      <div>{text}</div>
      <button onClick={() => {
        dispatch(increment())
      }}>添加</button>
      <button onClick={() => {
        dispatch(addItem())
      }}>list addItem</button>
    </>
  )
}

export default Todo

小结: redux 其实很简单,就是一个存储对象,提供一些方法存储、更新、监听、获取的方法给到我们,供我们做组件间的数据通信。