zoukankan      html  css  js  c++  java
  • redux 管理你的 react 应用

             Redux-(Reducer,Action,Store)

    action: 相当于新闻摘要,是一个用于描述已发生事件的对象,把数据从应用传入 store, 是一个 JS 对象,必须包含一个 Type 字段,只有触发 action 才能修改 state, 只有 state 改变才能触发 render() 函数,只有 render 函数调用才能更新 UI.

     store:唯一的,存储应用所有 state ,创建一个 store:let store  = createStore(reducer)

    store 有一个 dispatch 函数,他关注应用的业务实现逻辑,你可以用 dispatch 函数分发一个 action 到你定义的 reducer 函数, reducer 函数就是具体说明如何通过 action 改变 state , store 会分发这个 action 对象到它所拥有的所有的 reducer 函数来影响应用的状态,当然只有真正关注该 action 逻辑的 reducer 才会真正改变 state,这些都是中间件来完成的.

    store.dispatch(action)分发 action reducer.

    reducer:action 只是描述一个已发生事件,触发 action 才会改变 state, reducer 就是说明 action 如何改变 state ,他是一个纯函数,接受一个先前的 state 和一个 action, 并返回一个新的 state, 所有订阅 store.subscribe(listener)的监听器都将被调用, store.getState() 获取新的 state, component.setState(newState)更新 UI.

    Middleware: redux 中间件被设计成可组合的,会在 dispatch 之前调用的函数,创建一个日志中间件,它会简单的输出 dispatch 前后的应用状态, redux中间件的签名:middleware::next -> action -> retVal

    Snip20160901_26.png

    Snip20160901_27.png

    使用 redux的一个好处就是他让 state 的变化过程变得可预知和透明,每当一个 action 发起之后,新的state 就会被计算和保存下来, state 不能被自身修改,只能由特定的 action 引起变化.

    1.应用中所有的 state都以一个对象树的形式储存在一个单一的 store 中(注意:只有一个 store,reducer 可以拆分成多个子 reducers);

    2.唯一改变 state的方法是触发 action, action 是一个描述发生什么的JS对象,必须包含一个 type 字段, 调用 store.dispatch(action)触发action把数据传入 store,只有改变 state才能 触发 render() 函数才能重新渲染 UI.

    3.为了描述 action 如何改变 state树,你需要编写 reducer,这是一个普通的函数,接收先前的 state 和 action, 并返回新的 state.reducer 必须是纯净的.

    4.把要做的修改变成一个普通对象,这个对象叫做 Action, 而不是直接修改 state.然后编写专门的函数来决定每个 action 如何改变应用的 state, 这个函数叫做 reducer.

    5.跟 flux 的区别是只有一个单一的store 和一个根级的 reducer.随着应用的变大,应该把根级的 reducer 拆分成多个小的 renducers,分别独立的操作 state 树的不同部分,而不是添加新的 store.

    6.他的美在于做复杂应用和庞大系统时优秀的扩展能力,由于它可以用 action 追溯应用的每一次修改.

    (state,action) => state 的函数 这是一个 reducer, 描述了 action 如何把 state 转变为下一个 state.

    function counter(state = 0, action) {

      switch (action.type) {

      case 'INCREMENT':

        return state + 1;

      case 'DECREMENT':

        return state - 1;

      default:

        return state;

      }

    }

    创建 Redux store 来存放应用的状态

    API 是 subscribe dispatch  getState

    Snip20160901_24.png

    let store = createStore(reducer);

    store.subscribe(()=>

    console.log(store.getState())

    );

    改变内部 state 唯一的方法是 dispatch 一个 action,

    Snip20160901_25.png

    action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行

    store .dispacth({type:INCREMENT});

    Action:

    把数据从应用传到 store 的有效载荷,他是 store 数据的唯一来源,一般通过 store.dispatch() 将 action 传到 store.

    const ADD_TODO = ‘ADD_TODO’

    {

    type:ADD_TODO,

    text:’Build my first Redux app’

    }

    action 本质上是 JS 普通对象(就是键值对),action 内 必须使用一个字符串类型的 type 字段来表示将要执行的动作,多数情况下, type 会被定义成字符串常量,当应用的规模越来越大的时候,使用单独的模块或文件来存放 action,如:

    import{ADD_TODO,REMOVE_TODO}from’../actionTypes’

    action 创建函数:就是生成 action的函数,在redux 中的 action 创建函数只是简单的返回一个 action: function addTodo (text){

    return{

    type:ADD_TODO,

    text

    }

    }

    redux 中只需把 action 创建函数的结果传给 dispatch ()方法即可发起一次 dispatch 的过程

    dispatch(addTodo(text))

    或者创建一个被绑定的 action 创建函数来自动 dispatch:

    const boundAddTodo = (text) => dispatch (addTodo(text)) 然后直接调用 boundAddTodo(text);

    store 里能直接通过 store.dispatch() 调用 dispatch() 方法,但是多数情况下会使用 react- redux提供的connect() 帮助器来调用. bindActionCreators()可以自动把多个 action 创建函数绑定到dispatch() 方法上.

    Reducer:

    action 只是描述了有事情发生这个事实,并没有指明应用如何更新 state, 而这正是 reducer 要做的时,

    reducer 必须要保持纯净,永远不要在 reducer 里做这些操作:

    修改传入参数;

    执行有副作用的操作,如 API 请求和路由跳转;

    调用非纯函数,如 Date.now() 或 Math.random()

    我们将以指定的 state 的初始状态作为开始, redux 首次执行时, state 为 undefined, 此时我们可借机设置并返回应用的初始 state.

    import {VisibilityFilters}from ‘./actions’

    const initialState = {

    visibilityFilter:VisibilityFilters.SHOW_ALL,

    todos:[]

    };

    function todoApp (state,action){

    if (typeof state === ‘undefined’ ){

    return initialState

    }

    return state

    }

    function todoApp(state = initialState, action) {

      switch (action.type) {

        case SET_VISIBILITY_FILTER:

          return Object.assign({}, state, {

            visibilityFilter: action.filter

          })

        default:

          return state

      }

    }

    Redux -Store

    store 有以下的职责:

    维持应用的 state;

    提供 getState()方法获取 state;

    提供 dispatch(action)方法更新 state;

    通过 subscribe(listener)注册监听器;

    通过 subscribe(listener)返回的函数注销监听器;

    redux应用只有一个单一的 store

    根据已有的 reducer 创建store

    import { createStore}from ‘redux’

    import todoApp from ‘./reducers’

    let store  = createStore(todoApp)

    import { addTodo, toggleTodo, setVisibilityFilter, VisibilityFilters } from './actions'

    // 打印初始状态

    console.log(store.getState())

    // 每次 state 更新时,打印日志

    // 注意 subscribe() 返回一个函数用来注销监听器

    let unsubscribe = store.subscribe(() =>

      console.log(store.getState())

    )

    // 发起一系列 action

    store.dispatch(addTodo('Learn about actions'))

    store.dispatch(addTodo('Learn about reducers'))

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

    store.dispatch(toggleTodo(0))

    store.dispatch(toggleTodo(1))

    store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))

    // 停止监听 state 更新

    unsubscribe();

    数据流

    redux 中的数据的生命周期遵循4个步骤

    1.调用 store.dispatch(action )

    2.store 中调用传入的 reducer 函数

    注意: reducer 是一个纯函数,他仅仅用于计算下一个 state, 他应该是完全可以预测的,多次传入相同的输入必须产生相同的输出,他不应做有副作用的操作,如 API 调用或路由跳转,这些应该在 dispatch action 前发生

    3.根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树

    4.store 保存了根 reducer 返回的完整的 state 树,这个新的树就是应用的下一个 state, 所有订阅 store.subscribe(listener)的监听器都将被调用;监听器里可以调用 store.getState() 获得当前 state, 现在可以用新的 state 来更新 UI, 如果使用了 react redux 这类的绑定库,这时就可以调用 component.setState(newState)来更新.

    API文档

    createStore(reducer,[initialState])

    创建一个一个 store 存放应用中所有的 state

    参数: 

    1.reducer(Function):接受两个参数,分别是当前的 state 和要处理的 action, 返回一个新的state 树.

    2.[initialState](any):初始时的 state

    返回值:

    store 中保存所有的 state 对象,改变 state 唯一的方法是 store.dispatch(action).也可以用 subscribe 监听 state 的变化,然后更新 UI.

    (1)如果 state 是普通对象,永远不要修改它,比如 reducer 里不要使用 object.assign(state,newData),应该使用 Object.assign({},state,newData),这样才不会覆盖旧的 state

    (2)当 store 创建后, redux 会 dispatch 一个 action到 reducer 上,来用初始的 state 填充 store, 你不需要处理这个 action, 但要记住,如果第一个参数也就是传入的 state 如果是 undefined 的 话, reducer 应该返回初始的 state 的值.

    store 方法

    getState()

    dispatch(action)

    subscribe(listener)

    replaceReducer(nextReducer)

    combineReducers(reducers)

    把一个由多个不同 reducer函数作为 value 的 object, 合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore

    合并后的 reducer 可以调用各个子 reducer, 并把他们的结果合并成一个 state 对象, state 的结构由传入的多个 reducer 的key 决定.

    Snip20160901_20.png

    Snip20160901_21.png

    Snip20160901_22.png

    Snip20160901_23.png

  • 相关阅读:
    使用 mesh 实现多边形裁剪图片!Cocos Creator!
    如何实现高抛平抛发射?从抛物线说起!Cocos Creator!
    用 shader effect 实现雨滴落水效果!Cocos Creator 3D !
    反复横跳的瞄准线!从向量计算说起!基于射线检测的实现!Cocos Creator!
    爬取网易云音乐评论!python 爬虫入门实战(六)selenium 入门!
    浅析射线检测 raycast 的使用 !Cocos Creator 3D !
    用 python 分析基金!让赚钱赢在起跑线!
    cocos creator 3D | 拇指投篮 | 3D项目入门实战
    GA/T 1545-2019 信息安全技术 智能密码钥匙安全技术要求
    GA/T 1539-2018 信息安全技术 网络病毒监控系统安全技术要求和测试评价方法
  • 原文地址:https://www.cnblogs.com/ChrisZhou666/p/5888700.html
Copyright © 2011-2022 走看看