前面的文章中已经提到,在react开发中一切皆函数,我们可以将前端页面中的各种元素抽象成一个函数组件,便于管理和复用。但是,当页面存在较多组件时,组件间信息传递就会变得复杂。如下图所示,假设开发一个问卷信息系统,其中问卷模块被抽离成第三层的子组件,对于左侧流程图,如果希望在问卷组件中获取userId(用这个值获取问卷信息)就需要从Home组件一层层传递下来(当然也可以从session中读取值,这里只是举个栗子)。因此,从逻辑上思考,我们肯定希望该过程类似于右侧流程图,将一些多个组件都会用到的参数放在一个地方进行管理(读写),这就产生了redux(vue中使用vux,思想是类似的)。下文为了便于叙述,将redux保存的变量视为全局变量state。
-- Brisk Yu
一 redux相关库的安装
redux的相关操作较为复杂,因此本文基于redux-toolkit库实现redux,这也是新版redux官方推荐的方法。需要安装的相关库有redux、react-redux、redux-toolkit,使用npm安装上述包的方法网上较多,这里就不再赘述。
二 初始化全局变量以及相关操作(相关配置)
使用redux的第一步,就是需要定义有哪些会用到的全局变量,以及对这些全局变量会有怎样的操作(例如最简单的操作:赋新值)。如下代码所示,我们创建了一个slice,可以理解为slice就是一个包含了全局变量初始值(initialState)和相关操作(reducers)的东西。从slice的英文也可以看出,一个redux中可能包含多个slice,因此我们可以将不同用途的全局变量放置于不同的slice中。
const userInfoSlice = createSlice({ name: 'userInfo', initialState: { userId: '', password: '', userType: '' }, reducers: { setUserInfo: (state, action) => { state.value = action.payload } } })
为了使工程目录较为清晰,我们在创建了src/redux/store.js文件,并将上述代码写在该文件中。为了在其它组件中可以使用该文件中的数据,需要在该文件结尾export一些小编,如下所示。
export const { setUserInfo } = userInfoSlice.actions; export default userInfoSlice.reducer
注意第一行后面有个分号。通过上述代码,我们export出了userInfoSlice的actions 和 reducer (可以理解为actions和reducer都是slice中的reducers,是对于全局变量的一些操作)
三 告诉代码需要在哪里使用redux(将redux引入react工程)
转到需要使用redux的最高父组件处,本文就是index.js中的root。首先import步骤二中的slice,如下所示。
import userInfoReducer from "./redux/store"
注意这里import出的名称和slice中的name相关。接下来,通过configureStore API创建一个store
const store = configureStore({ reducer: { userInfo: userInfoReducer } })
最后,使用Provider元素包裹需要使用redux的最高父组件,并传入store
root.render( <Provider store={store}> <App /> </Provider> );
这样,就已经在react工程中引入了redux,后面便可以在各个组件中对全局变量进行读写啦~
四 写入全局变量
我们来到该项目的登录组件,首先将用户登录的相关信息写入store。
这里插一句,同vux一样,redux中不允许直接对store中的全局变量进行修改。有位网友举得例子很恰当,就好像当你浏览别人的PYQ发现一个错别字,你不能直接修改,而是通知这位朋友进行修改;同样道理,组件不能直接修改store中的全局变量,但是可以通知action进行修改。
我们在步骤二export了一个setUserInfo的action,这里就用这个action对全局变量进行写操作。首先import需要的小编:
import { setUserInfo } from "../redux/store"; import { usedispatch } from "react-redux";
const dispatch = usedispatch()
通过该hook,调用action,并将值传入
dispatch(setUserInfo(v))
回顾上文对于该action的定义,我们会用变量v给全局变量赋值。
五 读取全局变量
全局变量的读取较为简单,直接通过useSelector即可。同样的,首先import需要的小编
import { useSelector } from "react-redux";
const userInfo = useSelector(state => state)
const onClick = () => { console.log(userInfo.userInfo.value) }
六 总结
在react中使用redux构建全局变量,解决了不同组件间参数传递的问题,另不同组件可以访问全局变量进行读写。但是react中redux的配置较为麻烦,因此本文介绍了如何基于redux-toolkit进行redux的配置。通过该方法,使代码的逻辑更加清晰,并更加类似于vue中的vux。