Redux 概念和基本用法
前言
本文主要以 Rudex 结合 Racte 的方式,对 Redux 的基本概念和用法进行记录;
Rudex 是什么
Rudex 是一个以集中式 Store 的方式对整个应用中使用的状态进行集中管理,确保状态只能以可预测的方式更新;
简单来讲:Rudex 是一个状态管理库;
明确了 Rudex 是什么之后,需要思考两个问题:
- 为什么要使用 Rudex?
- 什么时候应该使用 Rudex?
Redux 设计理念
- 应用程序中发生了某些事情,例如用户单击按钮,用户发出 Action
- Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action; Reducer 会返回新的 State ;
- 组件内部通过订阅 store 中的状态 state 来刷新自己的视图
Rudex 三大原则
- 单一数据源
整个应用的 state 被储存在一个状态树中,并且这个状态树只存在于唯一的 store 中; - State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象; - 使用纯函数来修改
为了描述 action 如何改变 state tree,你需要编写纯的 reducers;
安装
Rudex 核心
npm install redux --save
基本概念和API
提示:本节的示例和说明只需要安装 Redux 核心就可以了;
-
Store
Store 是保存数据的地方,它是一个对象,一个应用只能有一个 Store;
Rudex 提供了一个叫createStore
的方法用来生成 Store;import { createStore } from 'redux'; const store = createStore(fn);
上面代码中,
createStore
方法接收一个函数作为参数,返回一个 Store 对象; -
State
Store对象包含所有数据, State 代表某个时间点的 Store, 用来描述应用程序在特定时间点的状况;
获取当前时间点的 State:store.getState()
import { createStore } from 'redux'; const store = createStore(fn); const state = store.getState();
Redux 规定一个 state 对应一个 View, 只要 state 相同,view 就是一样的,反过来也一样;
-
Action
State 的变化会导致 View 变化,但是用户接触不到 State,只能通过 View 发出一个由 Rudex 提供的一个叫 Action 的通知来告诉 Store, State 要发生变化了;
Action 是一个对象;Action 对象中的type
属性是必须的,表示 Action 的名称,其他属性可以根据需求自由设置;const action = { type: 'counter/add', payload: 'Add Operation' };
上面代码中,Action 的名称是
counter/add
, 携带的数据是字符串Add operation
, Action描述当前发生的事情,这是改变 State 的唯一的方式; -
Action Creator
View 可能会发很多种通知,会导致有多种 Action,可以定义一个函数生成 Action, 这个函数就叫 Action Creator;const add_counter = 'counter/add'; function addCounter(text) { return { type: add_counter, text } } const action = addCounter('Add Operation');
上面代码中,addCounter 函数就是一个 Action Creator;
-
store.dispatch()
store.dispatch()
是 View 发出 Action 的唯一方法;import { createStore } from 'redux'; const store = createStore(fn); store.dispatch({ type: 'counter/add', payload: 'Add Operation' })
上面代码中,
store.dispatch()
接收一个 Action 对象作为参数,将它发送出去;
结合 Action Creator,可以改写成这样:const action = addCounter('Add Operation'); store.dispatch(action);
-
Reducer
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化;这种 State 的计算过程 就叫做 Reducer;
Reducer 是一个纯函数,接收 Action 和当前 State 作为参数,决定如何更新状态,返回一个新的 State;注意:Reducer 必须是一个纯函数,也就是说函数返回的结果必须由参数 state 和 action 决定,而且不产生任何副作用也不能修改 state 和 action 对象;
const reducer = (state, action) => { switch (action.type) { case 'counter/add': return new state; default: return state; } };
实际应用中,
store.dispatch
方法会触发 Reducer 的自动执行; 为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 函数传入 createStore 方法;import { createStore } from 'redux'; const store = createStore(reducer);
上面代码中,createStore 接收 Reducer 作为参数,生成一个新的 Store,以后每当 store.dispatch 发送过来一个新的 Action,就会自动调用Reducer,得到新的 State;
-
store.subscribe()
Store 允许使用store.subscribe
方法设置监听函数,一旦 State 发生变化,就自动执行这个函数;import { createStore } from 'redux'; const store = createStore(reducer); store.subscribe(listener);
只要把 View 的更新函数放入 listen, 就会实现 View 的自动渲染;
store.subscribe
方法返回一个函数,调用这个函数就可以解除监听;const unsubscribe = store.subscribe(() => console.log(store.getState()) ); unsubscribe();
一个计数器示例:
点击查看代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createStore } from 'redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
const Counter = (props) => {
const {value, onAdd, onRemove} = props;
return (
<div>
<span>{value && value.counter}</span>
<button onClick={onAdd}>增加</button>
<button onClick={onRemove}>减少</button>
</div>
);
}
const defaultState = {
counter: 0
}
const reducer = (state = defaultState, action) => {
switch (action.type) {
case "counter/add":
return { ...state, counter: state.counter + 1 };
case "counter/remove":
return { ...state, counter: state.counter - 1 };
default:
return state;
}
}
const store = createStore(reducer);
const render = () => {
root.render(
<React.StrictMode>
<Counter
value={store.getState()}
onAdd={() => store.dispatch({type: 'counter/add'})}
onRemove={() => store.dispatch({type: 'counter/remove'})} />
</React.StrictMode>
);
}
render();
store.subscribe(render);
小结
- Redux 使用 "单向数据流"
- State 描述了应用程序在某个时间点的状态,UI 基于该状态渲染
- 当应用程序中发生某些事情时:
- UI dispatch 一个 action
- store 调用 reducer,随后根据发生的事情来更新 state
- store 通知 UI state 发生了变化
- UI 基于新 state 重新渲染
- Redux 有这几种类型的代码
- Action 是有 type 字段的纯对象,描述发生了什么
- Reducer 是纯函数,基于先前的 state 和 action 来计算新的 state
- 每当 dispatch 一个 action 后,store 就会调用 reducer
使用 React-Redux
介绍
React-Redux 是 Redux 的官方 React 绑定库;它能够使你的 React 组件从 Redux store 中读取数据,并且向 store 分发 actions 以更新数据;
安装
适用于 React 的 Redux 依赖包
npm install react-redux --save
使用 Redux Toolkit
安装
在既有项目上添加 Rudex Toolkit 依赖
npm install @reduxjs/toolkit --save
重新创建一个 React Rudex 应用
npx create-react-app my-app --template redux
未完待续。。。