在React中使用Redux(一)—— 初识Redux
大家早上中午下午晚上好呀,这里是小黑的前端频道。如题,这是一篇很详细的redux教程,看完还不懂,那就看第二遍,第三遍🤨...
Redux的核心思想
纯函数
在写Redux的核心思想之前,我们需要先理解纯函数的概念,因为后面的介绍中有一个reducer的概念,要求这必须是一个纯函数。维基百科对纯函数的定义是:
- 在程序设计中,若一个函数
符合以下条件
,那么这个函数被称为纯函数: - 此函数在
相同的输入值
时,需产生相同的输出
- 函数
与输出和输入值以外的其他隐藏信息或状态无关
,也和由I/O设备产生的外部输出无关
- 该函数不能有
语义上可观察的函数副作用
,诸如‘触发时间’,使输出设备输出,或更改输出值以外物件的内容等。
那么什么是副作用呢,在计算机科学中,副作用是指在执行一个函数时,除了返回函数值之外,还对调用函数产生了附加的影响,比如:修改了全局变量,修改参数或者改变外部的存储
总结: 纯函数在函数式编程中是非常重要的:
- 它可以让我们
安心的编写和安心的使用
- 我们只需要
单纯实现自己的业务逻辑
即可,不需要担心传入的内容是如何获得的,或者依赖其他的外部变量是否已经发生修改 - 我们在用的时候不用担心自己写的
内容是否被篡改
并且自己确定的输入
一定会有确定的输出
React非常灵活,但它也有一个严格的规则:所有React组件都必须像纯函数一样保护它们的props不被修改,后面我们学到的reducer也被要求是一个纯函数
为什么需要redux
- 随着JavaScript开发的应用程序变得越来越复杂,需要管理的状态越来越多,管理不断变化的state是非常困难的,
状态之间相互会存在依赖
,当应用程序复杂时,state的变化会变得非常难以控制和追踪
- React是在视图层帮助我们解决了DOM的渲染过程,但是State依然是留给我们自己来管理
- Redux就是一个帮助我们管理State的容器,提供了可预测的状态管理;(这里需说明一下,redux并不是react特有的状态管理库,也可以和其他界面库一起使用比如vue,并且redux非常小)
Redux做了什么
假如我们有一个列表数据,如果没有定义统一的规范来操作这段数据,那么整个数据的变化就是无法追踪的。
state:我们需要将一些需要统一管理的状态放在一个state
中,并由store
来管理这个state。
action:Redux要求我们通过action
来更新数据,所有数据的变化都需要通过派发action来更新,action是一个普通的JS对象,用来描述这次更新的type
和content
。
reducer:如何将state和action联系在一起呢,这时reducer
就派上用场了,reducer是一个纯函数,他将我们传入的state和action结合起来生成一个新的state
Redux的使用
redux使用的三大原则
- 单一数据源 整个应用程序的state被存储在一颗object tree中,并且这个object tree 只存储在一个store中 Redux并没有强制不让我们存储在多个state中,但是那样做不利于维护数据 单一的数据源可以让整个应用程序的state变得方便维护、追踪和修改
- State是只读的 唯一修改State的方法一定是触发action,不要试图在其他地方通过任何的方式来修改State 这样就确保了View或网络请求都不能直接修改state,它们只能通过action来描述自己想要如何修改state 这样可以保证所有的修改都被集中化处理,并且按照严格的顺序来执行
- 使用纯函数来执行函数 通过reducer将 旧state和 actions联系在一起,并且返回一个新的State 随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同state tree的一部分 但是所有的reducer都应该是纯函数,不能产生任何的副作用
redux的使用过程
- 1.创建一个对象,作为我们要保存的状态
- 2.创建Store来存储这个state
- 创建store时必须创建reducer
- 我们可以通过
store.getState
来获取当前的state
- 3.通过
action
来修改state- 通过
dispatch
来派发action - 通常action中都会有type属性,也可以携带其他的数据
- 通过
- 4.修改reducer中的处理代码
- 这里一定要记住,reducer是一个纯函数,不需要直接修改state
- 5.可以在派发action之前,监听store的变化
安装redux
npm install redux --save
# 或
yarn add redux
- 创建一个文件夹(假设是learn-redux),在该文件下执行
npm init
或yarn init
- 创建src目录,在该目录下新建index.js文件
- 修改package.json,使其执行index.js文件
"scripts": {
"start": "node src/index.js"
}
开始在我们的index.js中编写代码
1、创建一个对象,作为我们要保存的状态,对象中有一个counter属性
const redux = require('redux');
const initialState = {
counter: 0
}
2、创建store来存储这个state
- 创建store时必须创建reducer;
- 我们可以通过
store.getState
来获取当前的state
// 创建reducer
const reducer = (state = initialState, action) => {
return state;
}
// 根据reducer创建store
const store = redux.createStore(reducer);
console.log(store.getState());
3.通过action来修改state
- 通过dispatch来派发action;
- 通常action中都会有type属性,也可以携带其他的数据;
store.dispatch({
type: "INCREMENT"
})
store.dispath({
type: "DECREMENT"
})
store.dispatch({
type: "ADD_NUMBER",
number: 5
})
4.修改reducer中的处理代码
const reducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENT":
return {...state, counter: state.counter + 1};
case "DECREMENT":
return {...state, counter: state.counter - 1};
case "ADD_NUMBER":
return {...state, counter: state.counter + action.number}
default:
return state;
}
}
5.可以在派发action之前,监听store的变化:
store.subscribe(() => {
console.log(store.getState());
})
6、以上步骤借用coderwhy老师画的一个流程图来让大家更直观的理解redux在实际开发中做了什么
总结
这边文章让大家了解了Redux到底是什么,在应用程序中是怎么起作用的,后面我会继续写文章来讲解怎么在React中使用Redux,有没有什么更简单的方法可以替代原始的Redux的写法,有什么不对的地方希望大佬们批评指正哦
转载自:https://juejin.cn/post/7256386855720353851