今天来记录一下,在React中使用Redux的不同写法,从最开始的不依赖react-redux插件,到妥协(bushi),直到现在使用@reduxjs/toolkit插件进行编写,了解插件到底为我们做了什么(他真的,我哭死o(╥﹏╥)o)。
第一种,纯redux
创建store
/**
* 目前createStore已经弃用,所以我们要引用legacy_createStore
* compose:用来合成函数,在同时配置applyMiddleware、devtool时候需要引入
* applyMiddleware:使用中间件来增强store
* thunk:创建异步actions
* devtool:判断浏览器是否有安装调试的插件,有则启用
*/
import { legacy_createStore as createStore, compose, applyMiddleware, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import count from './features/count'
const devtool = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
export default createStore(
combineReducers({
count
}),
compose(
applyMiddleware(thunk),
devtool
)
)
创建reducer
/**
* 以一个简单的累加计数器为例
* reducer是一个函数,初始化会调用,所以要设置默认值
* 工作原理:根据传入的actionType,执行对应的逻辑
*/
const initState = 0
const reducer = (preState = initState, action) => {
const { type, playload } = action
switch (type) {
case 'add':
return preState + playload
default:
return preState
}
}
export default reducer
组件引用store
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import store from './store'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
)
// 监听state变化,更新视图
store.subscribe(() => {
root.render(
)
})
// HelloWorld.js
import React from 'react'
const HelloWorld = props => {
const store = props.store
return (
{/* 获取state */}
HelloWorld,{store.getState()}
{/* 通过dispatch触发调用reducer,传入约定好的action */}
)
}
export default HelloWorld
第二种,使用react-redux
与第一种的区别在于组件引用,不需要再手动监听state变化。同时组件分为UI组件、容器组件。UI组件所需的状态,更新状态的方法均由容器组件提供,通过props的方法传递。
组件引用store
// src/index.js
// 使用Provider组件注入store
import { Provider } from 'react-redux'
import store from './store'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
)
// HelloWorld.js
import React from 'react'
// 引入connect函数创建容器组件,ui组件不直接操作state
import { connect } from 'react-redux'
const HelloWorld = props => {
return (
HelloWorld,{props.value}
)
}
// 设置给UI组件展示的参数
const mapDispatchToProps = store => {
return {
value: store,
}
}
// 设置给UI组件调用的方法
const MapDispatchToPropsNonObject = {
add: payload => ({ type: 'add', payload }),
}
export default connect(
mapDispatchToProps,
MapDispatchToPropsNonObject
)(HelloWorld)
第三种,使用@reduxjs/toolkit + react-redux
创建store
// store/index.js
// 使用configureStore方法创建store
import { configureStore } from '@reduxjs/toolkit'
import countReducer from './features/count'
export default configureStore({
reducer: {
count: countReducer
}
})
创建reducer
// 使用createSlice创建reducer,createAsyncThunk创建异步actions
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
const request = () => {
return fetch('http://xxx.xxxxxxxxx.xxx').then(res => {
return res.json()
})
}
export const asyncReducer = createAsyncThunk('count/asyncAdd', async () => {
const res = await request()
return res
})
const slice = createSlice({
name: 'count',
initialState: {
value: 0,
list: [],
},
reducers: {
add(state) {
state.value += 1
},
},
// 监听异步action完成
extraReducers(builder) {
builder.addCase(asyncReducer.fulfilled, (state, { payload }) => {
state.list = payload.movieList
})
},
})
export const { add } = slice.actions
export default slice.reducer
组件引用
// HelloWorld.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { add, asyncReducer } from '../store/features/count'
const HelloWorld = () => {
// 从store中获取状态
const { value, list } = useSelector(store => {
return store.count
})
// 从store中对dispatch函数的引用
const dispatch = useDispatch()
return (
value:{value}
{list.length}
)
}
export default HelloWorld
总结
使用了插件之后,我们使用store不再需要手动监听state变化,更新视图;reducer的定义变得更加规范,方便维护;组件引用store也变得更加方便,减少了很多的代码量。提高了开发效率。
本文由mdnice多平台发布