上节课我们完成了数据共享的功能,那么这节课我们来讲一点新的东西

回顾

在开始这节课的内容之前,我们对上节课来做一个简单的回顾:

  • combineReducers函数整合reducer
  • combineReducers中接收一个参数是对象
  • combineReducers接收到的对象就是redux中的状态对象

以上便是上节课的内容,接下来我们来开始我们这节课的学习

纯函数

我们这节课来介绍一个概念叫纯函数,没有什么编码,就只是介绍概念。

我们先来回想一下:

import { ADD_PERSON } from '../constant';

const initState = []
export default function personReducer(preState = initState, action) {
  const { type, data } = action;
  switch (type) {
    case ADD_PERSON:
      return [data, ...preState];
    default:
      return preState;
  }
} 

这段代码的第7 ~ 8行我们在干什么?是不是添加一个人?我们是用的展开运算符来在这个数组的最前方添加了一个元素,对不对?那么我们非得这么写吗?如果我们像这么写

preState.unshift(data)
return preState

这段代码的效果是不是一样的啊?那么我来试一下:

image-20220120121225859

我们来看,我们这么写,虽然语法上是一点毛病都没有,但是我们没有成功添加一个人,那么是不是因为我们unshift这个操作没有成功呢?我们在控制台上输出一下呗:

image-20220120121506508

实际上我们其实已经正常添加了啊,但是为什么页面没有更新呢?因为redux会把我们return出来的statereturn之前的preState来做一个比较,如果一样的话,就认为我们的state没有发生改变。但是我们现在的数组好像是发生改变了啊,这里的比较其实是一个浅比较,我们用展开运算符生成的数组是不是一个新数组?内存地址实惠发生改变的,但是用push或者unshift依然还是在原数组上进行操作,内存地址是没有发生改变的,所以说这里返回前后内存地址没变redux就会认为没变。

而且如果这么写的话还会破坏一个原则,就是这么写的话reducer就不是一个纯函数了。

那么什么是纯函数呢?一个函数只要有同样的输入,必定会得到同样的输出,那么这个函数就被称之为纯函数。可能有人说,什么意思没懂。就比如说我们有一个函数叫func,如果func(1) === 1,那么在任何时候调用func(1)获取到的返回值都必须还是 1,如果用相同的参数调用函数得到了不同的结果,那么这个函数就不是纯函数。

那么为什么说我们像刚才那样改写reducer就不是纯函数了呢?因为纯函数必须要遵守一些约束:

  • 纯函数中不允许修改任何参数数据
  • 不产生副作用,例如网络请求等
  • 不允许在纯函数中调用不纯方法

那么我们来看我们的reducer,我们是不是用unshift方法修改了参数数据?所以说我们这样会导致reducer不再是一个纯函数。

总结

  • redux中的reducer必须是纯函数
  • 纯函数中不得执行任何有副作用或不纯的函数
  • 纯函数中不许修改参数数据

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/use_function_anywhere/