Redux基础

来源:互联网 发布:极乐净土动作数据镜头 编辑:程序博客网 时间:2024/06/03 21:17

1.是否需要redux

需要使用redux的情况

  • 多交互、多数据源

    • 用户的使用方式复杂呢
    • 不同身份的用户有不同的使用方式(比如普通用户和管理员)
    • 多个用户之间可以协作
    • 与服务器大量交互,或者使用了WebSocket
    • View要从多个来源获取数据
  • 从组建的角度看

    • 某个组件的状态需要共享
    • 某个状态需要任何地方都可以拿到
    • 一个组件需要改变全局状态
    • 一个组件需要改变另一个组件的状态

    需要一种机制,可以在同一个地方查询状态,改变状态,传播状态变化。

2.设计思想

  • web应用是一个状态机,视图与状态是一一对应的。
  • 所有的状态,保存在一个对象里面。

3.基本概念和API

3.1 Store

  • 一个容器,保存数据
  • 整个应用只有一个store
  • 用createStore函数生成Store

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

3.2 State

  • Store 包含所有数据
  • 得到某个时点的数据,对Store生成快照,这种时点的数据结合,就是State
  • 用store.getState()拿到

    import {createStore} from 'redux';const store= createStore(fn);const state=store.getState();
  • 一个State对应一个View。State相同,View就相同。

3.3 Action

  • State变化—导致View变化
  • 用户拿不到State,只能接触到View
  • View—导致State的变化
  • View–> 发出通知Action–> State变化

        const action={        type:'ADD_TODO',        payload:'Learn Redux'    }
  • 是一个对象

  • type是必须的 表示名称
  • 描述当前发生的事情
  • 改变State的唯一办法就是使用Action,Action运送数据到store

3.4 Action Creator

  • View发送多少消息,就有多少Action
  • 定义一个函数生成Action—–Action Creator

    const ADD_TODO='添加';function addTodo(text){    return {       type:ADD_TODO,       text    }}

3.5 store.dispatch()

  • View发出Action的唯一方法。
  • 接受一个Action对象作为参数。
  • 可以结合Action Creator。

    import {createStore} from 'redux';const store= createStore(fn);store.dispatch({addTodo('Learn')});

3.6 Reducer

  • Store接收到Action之后,给出一个新的state,这个计算过程叫做Reducer。
  • 这个新的State导致View的变化

    const reducer =function(state,action){      return new_state;}
  • 是一个函数,接收当前State和Action作为参数,返回新state

  • 可以添加state默认值

    const defaultState=0;const reducer=function(state=defaultState,action){     switch(action.type){         case:'ADD':               return state+action.payload;         default:               return state;     }};const state=reducer(1,{type:'ADD',payload:2})
  • Reducer函数不用手动调用

  • 将Reducer传入createStore中,store.dispatch会触发Reducer执行。
  • 因为可以作为reduce方法的参数,因此叫reducer。

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

3.7 纯函数

  • Reducer是纯函数,同样输入,同样的输出

    • 不得改写参数
    • 不能调用系统I/O的API
    • 不能调用Date.now和Math.random()等不纯的方法,
  • Reducer函数里面不能改变State,必须返回一个全新对象。

    //State是一个对象function reducer(state,action){     return Object.assign({},state,{thingToChange});     return {...state,...newState};}//State是一个数组function reducer(state,action){     return [...state,nemItem];}

3.8 store.subscribe()

  • 这个方法设置监听函数,一旦state发生变化,就自动执行这个函数
  • 把View的更新函数,对于React就是组件的render方法或setState方法,放入listen,就会实

现View自动渲染。

    import {createStore} from 'redux';    const store = createStore(reducer);    store.subscribe(listener);
  • store.subscribe方法返回一个函数,调用这个函数可以解除监听。

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

4.Store的实现

  • Store提供了三个方法

    • store.getState()
    • store.dispatch()
    • store.subscribe()

      import { createStore } from 'redux';let {subscribe,dispatch,getState}=createStore(reducer);
  • createStore 可接受第二个参数,State最初状态,如果有这个参数,会覆盖Reducer函数的

默认初始值。

    let store=createStore(reducer,window.STATE_FROM_SERVER);
  • createStore的简单实现

    const createStore=(reducer)=>{        let state;        let listeners=[];        const getState=()=>state;        const dispatch=(action)=>{           state=reducer(state,action);           listner.forEach(listener=>listener());               }        const subscribe=(listener)=> {            listeners.push(listener);            return ()=>{               listeners= listeners.filter(l => l!                ==listener);            }        }        dispatch({});        return {getState,dispatch,subscribe};           }

5.Reducer的拆分

  • Reducer函数负责生成State.
  • 整个应用只有一个State,包含所有数据,这个State必然十分庞大,导致Reducer
    函数也十分庞大。

  • 可以把Reducer函数拆分,不同函数处理不同属性,最后合成一个大的Reducer。

  • Redux中的combineReducers,用于Reducer的拆分。

    import {combineReducer} from 'redux';const chatReducer= combineReducer({     chatLog,     statusMessage,     userName})
  • 这种写法的前提,State的属性名与子Reducer同名。

  • 不同名需要

    const reducer = combineReducers({     a:doA,     b:doB,     c:doC});等同于function reducer (state={},action){    return {       a:doA(state.a,action),       b:doB(state.b,action),       c:doC(state.c,action)    }}
  • combineReducers()做的就是产生一个整体的Reducer函数,该函数根据State的key去执行相

应的子Reducer,并将返回结果合并成一个大的State对象。

    const combineReducers = reducers => {      return (state = {}, action) => {        return Object.keys(reducers).reduce(          (nextState, key) => {            nextState[key] = reducers[key](state[key], action);            return nextState;          },          {}         );      };    };
  • 统一引入

    import { combineRducers } from 'redux'import * as reducers from './reducers'const reducer=combineReducers(reducers);

参考整理自阮一峰博客
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

0 0