React 状态管理 的概述
redux 其实是一个第三方 数据状态管理的库,它不仅仅可以和react 结合使用,你也可以把它应用到 vue 中
Redux API
createStore(reducer, [preloadedState], enhancer);
- reducer (Function): 接收两个参数,分别是当前的 state 树和要处理的 action,返回新的 state 树。
- [preloadedState] (any): 初始时的 state。 在同构应用中,你可以决定是否把服务端传来的 state 后传给它,或者从之前保存的用户会话中恢复一个传给它。如果你使用 combineReducers 创建 reducer,它必须是一个普通对象,与传入的 keys 保持同样的结构。否则,你可以自由传入任何 reducer 可理解的内容。
- enhancer (Function): Store enhancer 是一个组合 store creator 的高阶函数,返回一个新的强化过的 store creator。这与 middleware 相似,它也允许你通过复合函数改变 store 接口。
- 返回值 (Store): 保存了应用所有 state 的对象。改变 state 的惟一方法是 dispatch action。你也可以 subscribe 监听 state 的变化,然后更新 UI。
reducer
- reducer(state,action)
Store
- getState()
- dispatch(action):dispatch传入action对象,触发reducer;
- subscribe(listener):subscribe用来监控state的变化,返回的参数用来取消监控;
- replaceReducer(nextReducer):replaceReducer替换reducer;
combineReducers(reducers)
将 reducer 函数拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分
applyMiddleware(...middlewares) 中间件
Redux三大原则
1. 单一数据源:整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中
2. state是只读的:唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象
3. 使用纯函数来执行修改
高阶函数和纯函数
高阶函数,至少满足下面一个条件的函数:1.接受一个或多个函数作为输入;2.输出一个函数
纯函数,1.相同的输入永远返回相同的输出;2.不改变函数的输入值;3.不依赖外部环境状态;4.无任何副作用
react-redux 的学习
类似于 Vue,React 中组件之间的状态管理 第三方包为:react-redux。react-redux 其实是 Redux的官方React绑定库,它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据。
react-redux: 其实是帮我们封装了 redux 连接 react 的一些操作,使用 react-redux 可以非常简单的在 react 中使用 redux 来管理我们应用的状态。
redux-thunk:使redux的action能够写异步方法,本身action中是不能写异步方法的,用了redux-thunk才可以。
react-redux API
react-redux 提供了两个常用的 api
Provider: 组件之间共享的数据是 Provider 这个顶层组件通过 props 传递下去的,store 必须作为参数放到Provider组件中去。
connect: 提供了组件获取 store 中数据或者更新数据的接口。
react-redux 落地操作(typescript 版)
1. 安装相关npm包
npm install redux react-redux redux-thunk --save
2. 创建仓库
在src目录下创建store文件夹继续在这个文件下创建index.ts 以及reducer.ts
index.ts
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
import thunk from "redux-thunk";
const store = createStore(reducer, applyMiddleware(thunk));
export default store;
reducer.ts
import { combineReducers } from "redux";
const initCount = {
count: 0,
};
// 修改count的方法
function count(state = initCount, action:any) {
switch (action.type) {
case 'COUNT_ADD':
return {
...state,
count: state.count + 1
}
case 'COUNT_REDUCE':
return {
...state,
count:state.count - 1
}
default:
return state
}
}
// combineReducers 合并多个reducer最终返回一个集成的reducer
export default combineReducers({
count,
});
3. 全局配置store (通过Provider)
import { createRoot } from 'react-dom/client';
import './common/style/globsl.css'
import App from './App';
import { Provider } from "react-redux";
import store from './store'
const container:any = document.getElementById('root');
const root = createRoot(container);
// 装载
root.render(
<Provider store={store}>
<App />
</Provider>
);
4. 在其他页面使用store数据
可以使用 react-redux的 connect去实现但是 但是,这里比较偏向函数是组件所以采用相关hooks来实现
/**
* hooks
* useDispatch获取dispatch
* useStore获取store
* useSelector获取state
*/
import { useDispatch, useSelector, useStore } from "react-redux"
import { Button } from 'antd';
const Homeone = (props:any) => {
const dispatch = useDispatch();
const count = useSelector((state:any)=>{
return state.count.count
});
const store = useStore();
console.log( 'store',store);
// 可以获取所有的仓库数据
console.log( 'store.getState',store.getState());
const changeCOunt =(type:string)=>{
dispatch({ type })
}
return (
<>
<div>当前页面信息 { count } </div>
<Button onClick={ ()=> changeCOunt('COUNT_ADD') }>添加</Button>
<Button onClick={ ()=> changeCOunt('COUNT_REDUCE') }>减少</Button>
</>
)
}
export default Homeone;