目录
store:存储所有应用的状态(一颗状态树state tree),单一可靠数据来源
发:派发(dispatch)行为(action)给store
const [state, dispatch] = [useSelector(state),useDispatch()]
const [state, dispatch] = useReducer(reducer, initialArg, init?)
3.useSelector((state)=> state.count):读取/订阅更新
4.useDispatch()({type:'inc',payload:5}):修改
Redux-Thunk 异步插件:从API加载 剩余商品列表
Redux-Persist 持久化:本地存储,记录用户登录状态,无需每次打开都要重新登录
Redux-immutable:不可变(immutable)的数据结构
在修改数据时,只有实际变化的部分会创建新的数据,其他部分会共享原有的数据,从而提高性能和内存利用率。
使用 Immutable.js 的不可变数据结构来存储 Redux 的状态。这样可以避免直接修改状态
引入原因
集中管理状态: 全局
React-Redux 提供了一个全局的状态存储容器(store),使得应用的状态可以在整个应用中进行集中管理。这有助于避免在组件之间传递大量的状态信息。
组件解耦:更关注UI
通过将状态逻辑从组件中抽离出来,可以使组件更加专注于 UI 的呈现,而不必担心状态的变化。这样可以提高组件的可复用性和可维护性。
单一数据源:易预测、调试
Redux 的设计理念是单一数据源,即整个应用的状态被存储在一个单一的 JavaScript 对象中。这使得状态的变化变得可预测且易于调试。
状态持久化:还原上次状态
核心
store:存储所有应用的状态(一颗状态树state tree),单一可靠数据来源
与组件通信区别
发:派发(dispatch)行为(action)给store
收:订阅store中的状态(state)来刷新自己的视图
state存储共享数据
action改变state
reducer根据action,返回新state
reducer(state,action){
根据action.type
return newState}
let { useReducer } = React;
let loginState = {//体现整体关联性与统一性**
isLogin: true,
isLogout: false
}
let loginReducer = (state, action) => {
switch(action.type){
case 'login':
return { isLogin: true, isLogout: false }
case 'logout':
return { isLogin: false, isLogout: true }
default:
throw Error('Unknown action: ' + action.type);
}
}
const [state, dispatch] = [useSelector(state),useDispatch()]
const [state, dispatch] = useReducer(reducer, initialArg, init?)
let Welcome = (props) => {
const [ state, loginDispatch ] = useReducer(loginReducer, loginState);
const handleLogin = () => {
loginDispatch({ type: 'login' });
}
const handleLogout = () => {
loginDispatch({ type: 'logout' });
}
return (
<div>
{ state.isLogin ? <button onClick={handleLogout}>退出</button> : <button onClick={handleLogin}>登录</button> }
</div>
);
}
步骤
1.主模块中进行注册 Provider组件
import { Provider } from 'react-redux'
import store from './store'
...
<Provider store={store}>
<App />
</Provider>
...
2.createStore(reducer)
import { createStore } from 'redux'
function counterReducer(state={count: 0}, action) {//reducer修改state
switch(action.type){
case 'inc':
return {count: state.count+state.payload}
default:
return state;
}
}
const store = createStore(counterReducer)
export default store
3.useSelector((state)=> state.count):读取/订阅更新
4.useDispatch()({type:'inc',payload:5}):修改
//其他组件,例如<Bar>组件中使用store
...
import { useSelector,useDispatch } from 'react-redux'
export default function Bar() {
const count = useSelector((state)=> state.count)//获取共享状态
const dispatch=useDispatch();//修改共享状态
const handleClick = () => {
dispatch({ //dispatch触发Reducer,分发action
type: 'inc',
payload: 5
})
}
return (
<div>
<button onClick={handleClick}>修改count</button>
Bar, { count }
</div>
)
}
相关
React-Redux:购物车中的商品列表,数量,总价
Redux-Thunk 异步插件:从API加载 剩余商品列表
Redux-Persist 持久化:本地存储,记录用户登录状态,无需每次打开都要重新登录
Redux-immutable:不可变(immutable)的数据结构
修改时不会改变原有数据,而是返回一个新的不可变数据结构
结构共享和持久化数据结构:
在修改数据时,只有实际变化的部分会创建新的数据,其他部分会共享原有的数据,从而提高性能和内存利用率。
List、Map、Set
const { List } = require('immutable');
const list1 = List([1, 2, 3]);
const list2 = list1.push(4); // 返回一个新的不可变数组 [1, 2, 3, 4]
使用 Immutable.js 的不可变数据结构来存储 Redux 的状态。这样可以避免直接修改状态
状态库对比特点
redux 唯一的价值就是看看源码了,学习一下思路
除了redux因为历史原因,zustand是用得最多的
Redux:中心化和可预测性
状态的变化都由 action 和 reducer 控制,这使得应用的状态变化可预测且易于调试。
纯函数reducer和分发操作:可预测
Redux 使用纯函数(reducer)来描述状态变化。当组件需要更新状态时,它会通过一个 action 对象来描述要执行的操作,然后 reducer 根据 action 类型来更新状态。
不可变状态(返回新,而非修改旧):追踪,调试
易于追踪状态变化,便于调试和理解:更容易地确定状态是如何变化的,以及何时发生的变化。
单一状态树:集中管理
Redux 使用单一的状态树来存储整个应用的状态。所有的状态都被保存在一个 JavaScript 对象中。
单项数据流:顶层向下传递
MobX:灵活
可直接修改状态值、但导致副作用
并发问题:如果多个部分同时尝试修改可变状态,可能会导致竞态条件和数据不一致的问题。使用不可变状态可以消除这种并发问题,因为状态不会被直接修改