Redux基础

安装

cnpm install react-redux redux --save

文档地址: http://cn.redux.js.org/docs/introduction/index.html

作用:无论是移动端还是 pc 端,当你使用 React 或者 vue 开发组件化的 SPA 程序时,组件之间共享信息是一个非常大的问题。例如,用户登录之后客户端会存储用户信息(如userid、头像等),而系统的很多个组件都会用到这些信息,例如收藏、点赞、评论等。这些组件在用到用户信息时,难道每次使用都重新获取一遍?———— 自然不是这样。因此每个系统都需要一个管理多组件使用的公共信息的功能,这就是 Redux 的作用。

Store

Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。

Redux提供createStore这个函数来生成store

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

上面代码中,creatStore函数接收了另一个函数作为参数,返回新生成的store对象

Store有两个核心方法,分别是 getStatedispatch 。前者用来获取store的状态(state),后者用来修改store的状态

Action

State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。
Action 是行为的抽象

    Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置
const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};

上面代码中,Action 的名称是ADD_TODO,它携带的信息是字符串Learn Redux。
可以这样理解,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。

Action Creator
View 要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator。

const ADD_TODO = '添加 TODO';

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

const action = addTodo('Learn Redux');

上面代码中,addTodo函数就是一个 Action Creator。

store.dispatch( )

store.dispatch()是 View 发出 Action 的唯一方法。将action传入到store
import { createStore } from 'redux';
const store = createStore(fn);

store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'
});

上面代码中,store.dispatch( ) 接受一个action对象作为参数,将他发送出去。
结合Action Creator,代码改写如下

store.dispatch(addTodo('Learn Redux'))

Reducer

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。而这正是 Reducer 要做的事情,更新 state

Reducer:是一个普通的函数,用来修改store的状态,传入两个参数state,action。其中state为当前的状态(可通过store.getState()获取),而action为当前触发的行为(通过store.dispath(action)调用触发)。

reducer(state,action)函数,返回store最新的state的值
eg:

const defaultState = 0;
//定义了一个reducer函数
const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};
//调用函数,返回新的state
const state = reducer(1, {
  type: 'ADD',
  payload: 2
});

上面代码中,reducer函数收到名为ADD的 Action 以后,就返回一个新的 State,作为加法的计算结果。

但是在实际应用中,Reducer函数并不需要像上面这样子调用,store.dispatch方法会触发Reducer的自动执行,为此Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。

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

上面代码中,createStore接收reducer作为参数,生成了一个新的store,所以当以后store.dispatch发送过来一个新的Action,就会自动调用Reducer得到新的state

为什么这个函数叫做Reducer呢?因为他可以作为数组的reduce方法的参数,JavaScript中reduce()方法不完全指南
eg:

const actions = [
  { type: 'ADD', payload: 0 },
  { type: 'ADD', payload: 1 },
  { type: 'ADD', payload: 2 }
];
const total = actions.reduce(reducer,0)  //3

上面代码中,数组actions表示依次有三个 Action,分别是加0、加1和加2。数组的reduce方法接受 Reducer 函数作为参数,就可以直接得到最终的状态3。

纯函数
Reducer函数最重要的特性是,他是一个纯函数,也就是说,只要是同样的输入,必定得到同样的输出

纯函数是函数式编程的概念,必须遵守一下的约束:

  • 不得改写参数
  • 不能调用系统 I/O 的API
  • 不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果

由于Reducer是纯函数,就可以保证同样的state,必定得到同样的view,但也正因为这一点,Reducer函数里面不能改变state,必须返回全新的一个对象,eg:

//state是一个对象
function reducer(state,action){
        return Object.assign({},state,{tingToChange})
        //或者
        return {...state,...newState}
}

//state是一个数组
function reducer(state,action){
    return [...state,newItem]

}

最好把 State 对象设成只读。你没法改变它,要得到新的 State,唯一办法就是生成一个新对象。这样的好处是,任何时候,与某个 View 对应的 State 总是一个不变的对象。

store.subscribe( )
Store允许使用store.subscribe方法设置监听函数,一但State发生变化,就会自动执行这个函数

import {createStore} from "redux"
const store = createStore(reducer)
store.subscribe(listener)

显然,只要把view的更新函数(对于react项目,就是组件的render方法或者setState方法)放入listener,就会实现view的自动渲染

store.subscribe方法返回一个函数,调用这个函数就可以解除监听

let unsubscribe= store.subscribe(()=>{
        console.log(store.getState())
})
unsubscribe()

combineReducers
Redux 提供了一个combineReducers方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。

import { combineReducers } from 'redux';

const chatReducer = combineReducers({
  chatLog,
  statusMessage,
  userName
})

export default todoApp;

上面代码中,Reducer 函数被拆成了三个小函数,每一个负责生成对应的属性。

combineReducers()做的就是产生一个整体的 Reducer 函数。该函数根据 State 的 key 去执行相应的子 Reducer,并将返回结果合并成一个大的 State 对象。

combineReducers

Redux 提供了一个combineReducers方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。

combineReducers()做的就是产生一个整体的 Reducer 函数。该函数根据 State 的 key 去执行相应的子 Reducer,并将返回结果合并成一个大的 State 对象。

这是一个reducer的小栗子:

const todo = (state,action)=>{
    switch(action.type){
        case "ADD_TODO":
            return {
                id: action.id,
                text: action.text,
                completed: false
            }

        case "TOGGLE_TODO":
            if(state.id !== action.id){return state}
    //取反,如果completed是ture返回false,反之亦然
    //state是对象的默认值,Object.assign方法将state和后面的对象合并成一个新对象,如果两者属性名相同,则后面的会覆盖前面的值
            return Object.assign({},state,{completed: !state.completed})

        default: return state
    }
}

你可能感兴趣的:(React)