Redux
redux是React技术栈使用最为广泛的状态管理
怎么学习Redux
记住“三个三”
第一个“三”(3个api):createStore、combineReducers、applyMiddleware
第二个“三”(3个特点):单一数据源、store只读、使用reducer纯函数修改store
第三个“三”(3个概念):State、Action、Reducer

安装Redux
npm i redux react-redux -S
Redux的简单案例
redux的状态管理配置
import { createStore } from 'redux' /** * 初始化可共享的状态数据 */ const initState = { msg: 'hello Redux', num: 1 } /** reducer一个函数 接受的参数为一个当前状态值(state)和一个对当前状值进行修改的对象方法(action) * reducer函数的格式为 (state,action) => newState * 注意:action =(type , payload,...) 其中前两项必须是这么写 redux规定了只能这么定义,使用其他变量就会报错 * reducer的state必须要为**对象、数组、原始数据**,其中根state通常是一个对象。你应该在状态改变时返回一个新的对象 newState */ /** **项目只有一个store时** */ function reducer(state=initState,action){ //action可以直接写为(type,payload)如果不写我们可以用action来结构 const {type,payload} = action // 注意:我们不能直接改变state的值,我们需要对其进行深复制后再进行改变 const newState = JSON.parse(JSON.stringify(state)) switch(type){ //当前端穿过来的type为’add‘时,触发下面的方法 case 'add': newState.num += payload break; ... } //最后抛出新值并存储在store中 return newState } /** * 创建一个redux store来存储状态值 * API是{ subscribe, dispatch, getState } */ const store = createStore(reducer)
当一个项目需要分多个子store时
// combineReducers 用于合并多个子store import { createStore,combineReducers } from 'redux' //这个里面存放子store——user的信息 import user from '/user' const reducer = combineReducers({user,...}) const store = createStore(reducer) export default store
引入redux状态管理
import React from 'react'; import {Provider} from 'react-redux'; import store from './store';//引入store数据 function App() { return ( <Provider store={store}> <T /> </Provider> ); } export default App;
redux状态管理 在JSX组件中的使用
/** * 使用connect将组件与状态管理链接起来 * connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) * mapStateToProps :将store.getState()返回的状态数据放在组件的props上 * mapDispatchToProps :用于建立组件跟store.dispatch的映射关系, 允许我们将 store中的dispatch方法,绑定到组件的props中。 *... */ import React from 'react'; import { connect } from 'react-redux'; export default connect( // 此处为mapStateToProps (state) => { //do somethings return { state } }, //此处为mapDispatchToProps (dispath) => ({ add: payload => dispath({ type: 'add', payload }) }) )((props) => { const { state, add } = props return ( <div> <h1>Redux的简单测试</h1> <h3>{state.reducer.num}</h3> <button onClick={() => add(1)}>自增+1</button> <button onClick={() => add(2)}>自增+2</button> <button onClick={() => add(-1)}>自增-1</button> </div> ) })

使用HOOK语法
import React from "react";
import { useSelector, useDispatch } from "react-redux";
export default () => {
// useSelector: 从redux中获取state数据
const state = useSelector(state => state)
// useDispatch:从redux中获取dispatch方法
const dispatch = useDispatch()
console.log(state);
console.log(dispatch);
return (
<>
<h1>使用Hook方式使用React</h1>
<h3>{state.reducer.num}</h3>
<button onClick={() => dispatch({type:'add',payload:1})}>自增+1</button>
<button onClick={() => dispatch({type:'add',payload:2})}>自增+2</button>
<button onClick={() => dispatch({type:'add',payload:-1})}>自增-1</button>
</>
)
}
深复制库
我们在之前的jsx中使用的深复制是JSON.parse(JSON.stringify( ))
这个虽然能实现store中state的深复制,但是其效率不高。因此,我们可以使用immer包进行深复制。
npm i immer -S
immer使用方法
对之前的jsx配置进行修改
import {
createStore,
combineReducers
} from 'redux'
import produce from 'immer';
// 初始化可共享的状态数据
const initState = {
msg: 'hello Redux',
num:1
}
/**
* reducer一个函数 接受的参数为一个当前状态值(state)和一个对当前状值进行修改的对象方法(action)
* reducer函数的格式为 (state,action) => newState
*注意:action =(type , payload,...) 其中前两项必须是这么写 redux规定了只能这么定义,使用其他变量就会报错
*/
function reducer(state = initState, action) {
const {
type,
payload
} = action
return produce(state,(newState)=>{
switch (type) {
case 'add':
newState.num +=payload
break;
//.....
}
})
}
const reducers = combineReducers({
reducer
})
const store = createStore(reducers)
export default store
装饰器语法
由于装饰器语法还未被W3C支持,因此我们需要安装babel插件用于解析装饰器
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
再在babel配置中引用插件
{
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties"]
]
}
对上述知识简单梳理
npm i redux -S
npm i react-redux -S
npm i immer -S
- 第一步,构建store的逻辑
const store = createStore(
combineReducers({good,user,...}),
compose(//对中间件进行合并处理
applyMiddleware(ReduxThunk),
applyMiddleware(ReduxLogger),
...
)
)
//引入immer 进行深复制
import produce from 'immer'
function reducer(state=initState, action) {
return produce(state, newState=>{
switch(action.type) {
case '':
}
})
}
export default reducer
- 第二步,连接redux和react
//导入一些依赖文件
......
function App() {
return (
<Provider store={store}>
{/* 在这里引入需要使用redux的组件*/}
.....
</Provider>
)
}
- 第三步,在react组件中使用store
- 如果是类组件, 只能使用 connect() 高阶组件.
@connect(
state=>({msg:state.user.msg, ....}),
dispatch=>({changeMsg:(payload)=>dispatch({type,payload})})
)
class Home extends PureComponent { }
export default Home
class Home extends PureComponent { }
export default connect(
state=>({msg:state.user.msg, ....}),
dispatch=>({changeMsg:(payload)=>dispatch({type,payload})})
)(Home)
- 如果是函数式组件, 使用 connect() 高阶组件
export default connect(
state=>({msg:state.user.msg, ....}),
dispatch=>({changeMsg:(payload)=>dispatch({type,payload})})
)(props=>(<div></div>))
- 如果是函数式组件(react v16.8),还可以使用react-redux的hooks写法
export default () => {
const msg = useSelector(state=>state.user.msg)
const dispatch = useDispatch()
}

本文详细介绍了Redux,一个广泛应用于React技术栈的状态管理库。通过'三个三'(3个API,3个特点,3个概念)来理解Redux核心,并提供了安装、简单案例、 Hook语法和immer库的使用。文章还涉及了如何在React组件中使用Redux,包括connect高阶组件和React Hooks。最后,讨论了使用immer进行深复制以提高效率。

2420

被折叠的 条评论
为什么被折叠?



