Redux 入门教程 之一

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请注明出处: http://blog.csdn.net/peng_cao https://blog.csdn.net/cpwolaichile/article/details/82469991

思想

  • web应用是一个状态机,视图与状态一一对应
  • 所有的状态都保存在一个对象中,这个歌对象叫Store

基本概念

Store

Store就是存储数据得地方,每一个应用智能有一个store,我们可以将其看成是一个容器。Redux提供了createStore(function)接口来生成一个store.
React-redux的createStore定义如下。
这里稍微解释下。createStore通常有三个参数。

  • getInfoReducercreateStore的第一个参数;其实质就是一个获取下一个状态的Reducer罢了。但是一个应用又不止一个Reducer但是store却只有一个,那么对应的创建store时传入的reducer也就只能有一个,这个时候combineReducers函数就能派上用处了。
  • initialState 就是一个初始状态
  • 第三个参数,我们通常称之为增强者,什么意思呢。就是说这里我们可以使用一些通用的第三方组件,称之为middleweare。而且Redux也规定了,唯一的Redux增强功能需要使用applyMiddleware来包装。
import thunk from "redux-thunk";
import { getInfoReducer } from "../reducers/getInfoReducer"
const initialState={};
const middleware = [thunk];

export const store = createStore(getInfoReducer, initialState, applyMiddleware(...middleware));

State

上一节我们知道Store对象包含了当前应用的所有数据;但是如果我们希望知道在某一时刻的数据,怎么搞?这个时候就需要提到一个叫State的概念了;可以将其理解为Store的在某一时刻的一个快照。可以通过如下方式获取当前的state。
还需要注意一点就是:Redux规定:一个View对应一个State,一个State对应一个View;换句话说,只要我们知道了View或者State中的任意一个我们就可以知道另外一个。
const state = store.getState();

Action

State的变化会导致View的变化;但问题是,用户根本接触不到State,只能接触到View,所以state的变化必须是由View引起的;那么View到底要如何改变State呢?答案就是这里介绍的Action啦。Action就是View发出的通知,表示State要改变了。
action是一个对象,type属性是必须的。定义如下所示:

const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};

可以这么理解:Action其实就是描述了当前发生的事情,是一个通道,用于连接View和State之间的一个桥梁。

Action Creator

View 要发出多少消息就有多少Action,记住:action只是一个通道,action知识告知有state发生了更改,但是更改了什么,也就是该action中携带了什么数据,action不care。那么可以想象下,假设有一个action叫:ADD。ADD可以携带各种各种数据。这个时候我们就可以将其抽象出来,使用一个叫Action Creator的方式来生成

const ADD_TODO="ADD_TODO";
function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
const todoAction = addTodo('Learn Redux');

例如这里的ADD_TODO就是一个action type,addTodo就是一个Action Creator,todoAction就是一个用Action Creator + 所需要携带的数据生成的一个action。这里可以这么理解

action = actionType + data

store.dispatch()

如上文提到的部分。我们已经拥有了action,拥有了要通过action发从的数据。但是怎么将整个action发出去呢?答案就是store.dispatch()
常见的写法如下。

import { createStore } from 'redux';
const store = createStore(fn);
store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'
});

这样写又太麻烦,结合我们上一步的将创建action抽象出来为function addTodo(text);该函数用于生成一个action

扫描二维码关注公众号,回复: 3207883 查看本文章
store.dispatch(addTodo('Learn Redux'));

Reducer

我们已经存储state的store,发送state的action,知道了通过action将数据发送出去;知道了可以通过dispatch 将action发从出去。但是数据怎么处理呢?
当store在收到发送过来的action 之后,必须给出一个新的state,这样View才能够根据该state重新渲染。reducer 是一个计算新state的过程。看下下面的整个例子

  • 首先是定义了一个reducer ,在该reducer中实现了ADD 功能。
  • 然后调用整个reducer来实现ADD功能,得到一个新的状态
const defaultState = 0;
const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};

const state = reducer(1, {
  type: 'ADD',
  payload: 2
});
// 此时state =3 ( 1 +2)

但是我们在实际使用过程不需要这么复杂。可以参考如下写法。
在通过createStore来生成store的时候,将reducer作为参数;这样后续通过store.dispatch发出的acion都会被自动的dispatch到作为参数的reducer中。

import { createStore } from 'redux';
const store = createStore(reducer);

const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};

const ADD_TODO="ADD_TODO";
function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
/* const todoAction = addTodo('Learn Redux'); */
store.dispatch(addTodo('Learn Redux'));

combineReducers

我们在上一步能看到,在使用createStore创建一个store时,将一个reducer作为入参传入;这样dispatch过来的action就可以被自动的dispatch到reducer中,并得到新的状态。那么问题来了。。我要是有多个,甚至是很多很多个reducer怎么办?而且每个应用的store只有一个,我不可能调用多次createStore来生成多个store吧。
其实还是有方法的。来看看createStore函数

const store = createStore(reducer)

我们store要每个应用只有一个,那就只能要求作为参数的reducer也就是只能有一个呀。麻蛋,这里就要使用到了combineReducers方法了。该方法可以将多个reducer封装成一个。我么就可以将当前应用的多个reducer使用combineReducer封装成一个reducer

const addReducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};
const addReducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'DIV':
      return state / action.payload;
    default: 
      return state;
  }
};
function createActionWithContent(action, content) {
  return {
    type: action,
    content
  }
}

const store = createStore(rootreducer)
const rootReducer = combinReducer({
    addReducer,
    divideReducer
});

store.dispatch(createActionWithContent("ADD",{payload: 2}))
// ....

完。。

猜你喜欢

转载自blog.csdn.net/cpwolaichile/article/details/82469991
今日推荐