上节课我们编写了Person组件的基本内容,这节课我们来编写他的reducer

回顾

在开始编写reducer之前按照惯例我们是要对上节课的内容来做一个简单的回顾的,但是上节课的内容没有什么新的知识点,我们就不再多说了,我们接下来开始这节课的内容。

分析

  • 现在redux相关内容都是已经完成好的
  • reduxstate中目前只存了一个Sum组件的求和
  • Person组件目前想要通过redux共享状态

那么我们现在是不是就不能只在redux里面存一个Sum的求和了?我们想要让Person组件在redux中加其他数据需要怎么做?是不是需要为Person组件来添加一个自己的reducer

redux分析

我打开redux的文件夹。这里面的内容都有哪些?

+
|-- redux
        |-- actions
        |       |-- *.js
        |-- reducers
        |       |-- *.js
        |-- constant.js
        |-- store.js

我们来看一下文件层级,两个文件件分别装着reduceraction,然后一个常量模块,一个store,那么我们先来看一下store需不需要修改。那么store里面都做了什么啊?

import { createStore,applyMiddleware } from 'redux';
import sumReducer from './reducers/sum';
import thunk from 'redux-thunk';

export default createStore(sumReducer, applyMiddleware(thunk));

我们来看一下代码,这里面是不是就只是创建了一个store啊?那么我们现在创建reducer需要动store里的东西吗?就目前来看是不是不需要?那么我们在来看常量模块里面需要修改吗?常量模块中是不是要为我们定义动作类型?我们reducer是不是要匹配动作类型?所以说常量模块是要往里面加东西的。

export const INCREMENT = "increment";
export const DECREMENT = "decrement";
export const ADD_PERSON = "add_person";

我们在常量模块中添加了一行ADD_PERSON变量。

创建action

那么常量准备好了我们是不是要为我们的组件来准备一个action?那么action怎么创建?是不是要先引入常量,然后定义一个函数?

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

export const createAddPersonAction = data => ({ type: ADD_PERSON, data });

我们来看一下,我们创建了一个函数createAddPersonAction,这个函数接收到数据然后返回一个动作对象。当然了其实我们上面这么写并不是太规范,我们接收到的data是不是应该是一个Person对象啊?所以说我们把参数给改一下

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

export const createAddPersonAction = personObj => ({ type: ADD_PERSON, data: personObj });

现在再来看就没有问题了。我接收到的参数和属性名不一样了,那么现在就不能用对象的简写方式了。

创建reducer

现在我们也创建好action了,action会由store来分发,那么分发给谁呢?是不是要分发给reducer?发给谁的reducer?是不是这个动作是哪个组件的,就分发给谁的reducer?那么好,我来问大家,现在这个action是不是Person组件的?那么是不是就要发给Person组件的reducer?那么Person组件有reducer吗?没有啊,那么我们来创建一个呗。

大家还记不记得怎么创建reducer啊?reducer是干什么的?是不是要根据动作来做一系列的事情?动作有动作类型,我们要在reducer里面来匹配动作类型,那么是不是要引入常量?而且reducer是不是要定义一个函数?那么好,我们来写一下:

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;
  }
}

我们来看一下代码,首先我们引入了常量,然后我们定义了一个空数组,并且在定义函数的时候把这个空数组作为默认参数传给preState,这是什么意思?我们在初始化状态的时候reducer接到的preState是不是undefined啊?那么我们就让preStateundefined的时候默认将preState置为这个初始化的空数组。

然后我们从action中取出typedata,然后switch来匹配动作类型,如果匹配到我们的ADD_PERSON动作的话就把data添加到数组中。那么这样我们的reducer就算是编写完成了。

包装参数

我们现在有了action,也有了reducer,那么我们是不是就可以把大致流程给串起来了?组件中发起,然后创建action,诶,等一下,我们创建action的时候接收的参数是不是一个对象?那么我们是不是要在onClick事件的回调中来把这个参数给包装好?

export default class Person extends Component {
  render() {...}
  addPerson = () => {
    const name = this.name.value;
    const age = this.age.value;
    const person = { id: nanoid(), name, age }
  }
}

这样我们是不是就包装好了一个对象。现在我们把参数也包装好了,那么接下来是不是直接发起,然后创建并分发action,然后交给reducer去干活了啊?当然了,这节课我们只是来把流程串起来,具体实现,我们下节课再说

总结

这节课也没有什么新的知识点,就多了一个默认参数传递的用法,这是原生js中的知识,大家一定要多回顾基础知识。

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/lesson110_share_data_person_reducer/