文章目录
一文讲清楚Redux、React-Redux和Redux Toolkit
1. 什么是Redux
首先,Redux是一个独立于React的状态管理库,我们只不过是在React项目当中管用Redux作为状态管理器,并且为了更好的在React中使用Redux,推出了React-Redux
Redux的设计理念是,所有的状态集中存放,集中管理,单向修改,也就是Redux的三大原则
- 单一数据源
Redux的所有状态都会被存储在一个对象树中,这个树存储在单一的store中 - 状态只读
状态是只读的,不能直接对状态进行修改操作,只能通过触发一个action来修改状态 - 纯函数更新
action描述了如何修改状态,修改状态的时候我们还需要原状态,因为产生了Reducer,Reducer接受旧的state和action,返回新的state
2. Redux三大组件
2.1 Store
Store是整个Redux应用的存储中心,通过createStore来创建一个Store,一个应用只可以有一个Store
import {createStore} from 'redux'
import myReducer from 'myReducer'
const store=createStore(myReducer)
2.2 Action
Action是一个对象,主要包含两个字段,type和payload(这个字段可以随便命名),type描述对state进行如何操作,payload可以传递额外的参数
const increment={
type:'ADD',
payload:4
}
2.3 Reducer
Reducer是一个纯函数,接收久的state和action,返回新的state,说白了,就是根据action.type判断要对旧的state怎么处理,处理完返回新的state,就这么简单
const initialState={
count:0
}
function reducer(state=initialState,action){
switch(action.type){
case 'ADD':
return{
count:state.count+action.payload
}
default:
return state
}
}
3. Redux使用
下面我们写一个简单的demo,来演示如何在React项目中使用Redux
先安装npm install redux react-redux
3.1 创建action
就是所有需要对状态操作集合的一个描述对象
创建一个action.js
export const increment=(amount)=>{
type:'INCREMENT',
payload:{amount}
}
export const decrement=(amount)=>{
type:'DECREMENT',
payload:{amount}
}
3.2 创建Reducer
reducer接受旧的state和action
创建一个reducer.js
const initState={
count:0
}
function reducer(state=initState,action){
switch(action.type){
case "INCREMENT":{
return {
count:state.count+action.payload.amount
}
}
case "DECREMENT":{
return {
count:state.count-action.payload.amount
}
}
default:
return state
}
}
export default reducer
3.3 创建Store
Store是唯一的状态存储,创建时,把reducer作为参数传递进去
创建store.js
import {createStore} from 'redux'
import reducer from 'reducer'
const store=createStore(reducer)
export default store
3.4 使用Store
在React应用中使用Provider将Store注入到应用中
修改index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import {Provider} from 'react-redux'
import store from 'store'
import App from 'App'
const root=ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Provider store={store}>
<App/>
</Provider>
</React.StrictMode>
)
3.5 使用connect连接
使用connect将React组件与Redux store连接
修改App.js
import React from 'react'
import {connect} from 'react-redux'
import {increment,decrement} from 'actions'
function App({
count,
increment,
decrement
}){
return(
<div>
<p>Count: {count}</p>
<button onClick={() => increment(1)}>Increment</button>
<button onClick={() => decrement(1)}>Decrement</button>
</div>
)
}
const mapStateToProps = (state) => ({
count: state.count
});
const mapDispatchToProps = {
increment,
decrement
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
4. Redux中间件
用过axios的童鞋都知道,我们可以在发送和接收请求之前,进行拦截,做一些业务处理,比如处理requestUrl或者处理requestStatus等
Redux的中间件非常类似,它允许我们在发出action之后,到达reducer之前,做一些业务处理,比如说进行网络请求
4.1 Redux-thunk
Redux-thunk是最常用的一个Redux中间件,用来进行异步操作
//修改action.js
export const fetchData=()=>{
return async(dispatch)=>{
const response=await fetch('requestUrl')
const data=await response.json()
dispatch({
type:'SET',
payload:data
})
}
}
//修改store.js,在穿件store的时候,传入Redux-thunk
import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import reducer from 'reducer'
const store =createStore(reducer,applyMiddleware(thunk))
export5 default store
5. @Reduxjs/toolkit
利用Redux和React-Redux虽然可以完整整个应用的状态管控,但是复杂的写法常常令人望而生畏,大篇幅的action和reducer代码,不仅编码慢,而且维护成本高
为了进一步简化redux的使用,@reduxjs/toolkit横空出世
5.1 configureStore
Redux Toolkit提供了configureStore来替代createStore,实现简单的store配置
import {configureStore} from '@reduxjs/toolkit'
import reducer from 'reduer'
export default configureStore({
reducer:{
reducer:reducer
}
})
5.2 createSlice
createSlice可以创建一个包含reducer和actions的slice,并通过name进行隔离
import {createSlice} from '@reduxjs/toolkit'
const initState={
count:0
}
export const counterSlice=createSlice({
name:'counterSlice',
initState,
reducers:{
increment(state){
state.counter+=1
},
}
})
export const {increment} =counterSlice.actions
export selectCount=(state)=>state.counterSlice.count
export default counterSlice.reducer