快速了解react技术栈中的redux,react-redux

1,redux

  1. redux简介
  • redux是这个技术栈中最难的一个环节。Redux 是 JavaScript 状态容器,提供可预测化的状态管理。可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。不仅于此,它还提供超爽的开发体验,Redux 除了和 React 一起用外,还支持其它界面库。
  1. redux核心
  • 应用中所有的 state 都以一个对象树的形式储存在一个单一的store中。惟一改变 state的办法是触发action,一个描述发生什么的对象。 为了描述 action 如何改变 state 树,你需要编写reducers。以上的基本需要都准备好后,就可以创建一个像仓库一样的store,把你的数据保护起来,每次访问必须发起action传给reducer,而不是直接修改里面的state。Redux不支持多个store。相反,只有一个单一的store和一个根级的reduce函数(reducer)。reducer拆成多个小的reducers,分别独立地操作state树的不同部分,而不是添加新的store。这就像一个React应用只有一个根级的组件,这个根组件又由很多小组件构成。
  1. 三大原则
  • (1)单一数据源
  • 整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree只存在于唯一一个store 中。这让同构应用开发变得非常容易。来自服务端的 state 可以在无需编写更多代码的情况下被序列化并注入到客户端中。让调试变得非常容易,从而加快开发速度。
  • (2)state是只读的
  • 唯一改变state的方法就是触发action,action 是一个用于描述已发生事件的普通对象。这样确保了视图和网络请求都不能直接修改state,相反它们只能表达想要修改的意图。所有的修改都被集中化处理,且严格按照一个接一个的顺序执行。
  • (3)使用纯函数修改
  • 为了描述action如何改变state tree,你需要编写 reducers。Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state。刚开始你可以只有一个 reducer,随着应用变大,你可以把它拆成多个小的 reducers,分别独立地操作 state tree 的不同部分,因为 reducer 只是函数,你可以控制它们被调用的顺序,传入附加数据。
  1. State
  • state是定义一些数据的,定义好的数据交给store集中管理。我们定义一些数据如下:
    this.state = {
        todos:[
            {content:"react",complete:false},
            {content:"redux",complete:true},
        ],
        visibility:"all"
    }
复制代码
  1. Action
  • Action 是把数据从应用传到store的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。action 本质上是 JavaScript 普通对象。我们约定,Action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下, type 会被定义成字符串常量。定义Action可以是const,也可以创建函数function,下面例子里用的是function。
  • 添加todo任务的action如下:
    function addTodo(text){
        return{
            type:"ADD_TODO",
            text
        }
    }
复制代码
  • 切换todo任务的action如下:
    function toggleTodo(todo){
        return{
            type:"TOGGLE_TODO",
            todo
        }
    }
复制代码
  • 设置可见性的action如下:
    function setVisibility(filter){
        return{
            type:"SET_VISIBILITY",
            filter
        }
    }
复制代码
  1. Reducer
  • Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。现在我们已经确定了 state 对象的结构,就可以开始开发 reducer。reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
  • 我们先定义todos状态下的reducer如下:
    function todos(state=[],action){
        switch(action.type){
            case "ADD_TODO":
               return[...state,{content:actiion.text,complete:false}];
            case "TOGGLE_TODO":
                return state.map(todo=>{
                    if(todo == action.todo){
                        return Object.assign({},todo,{complete:!todo.complete})
                    }
                    return todo;
                })
            default:
                return state;
        }
    }
复制代码
  • 接着我们定义visibility对应的reducer如下:
    function visibility(state = "all",action){
        switch(action.type){
            case "SET_VISIBILITY":
                return action.filter
            default:
                return state
        }
    }
复制代码
  • 每个 reducer 只负责管理全局 state 中它负责的一部分,所以我们要合并reducer,Redux 提供了 combineReducers() 工具类,让我们试试这个工具。
  • 现在合并上面两个reducer如下:
    const reducer = Redux.combineReducers({
        todos,
        visibility
    })
复制代码
  • 注意:
  • (1).不要修改 state 。 使用 Object.assign() 新建了一个副本。不能这样使用 Object.assign(state, { visibilityFilter: action.filter }) ,因为它会改变第一个参数的值。你必须把第一个参数设置为空对象。你也可以开启对ES7提案对象展开运算符的支持, 从而使用 { ...state, ...newState } 达到相同的目的。
  • (2).在 default 情况下返回旧的 state 。遇到未知的 action 时,一定要返回旧的 state。
  1. Store
  • 上面我们做了很多准备就是为了创建store,如下:
    const store = Redux.createStore(reducer);
复制代码
  • 我们创建好store,就是为了使用它。Store有如下几个API:
  • (1)getState:用于获取状态;
  • (2)dispatch:用于触发某个action;
  • (3)subscribe:订阅,一旦状态发生改变,就会执行回调函数。
  • 使用Store如下:
    console.log(store.getState());
    store.dispatch(addTodo);
复制代码
  • 再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。
  1. 异步Action
  • Action 发出以后,过一段时间再执行 Reducer,这就是异步。
  • 在进行webapp开发的时候,最典型的异步场景就是异步获取数据(使用ajax、axios、fetch等方式)。
  • 在异步的action中,其实应该返回一个函数,在函数中去调用同步的action即可。 这个函数,会自动的获取dispatch和getState。如下:
    function incrementAsync(){
        return function(dispatch,getState){
            setTimeout(function(){
                dispatch(increment());
                //这里调用同步的action,increment()
            },1000)
        }
    }
复制代码
  1. Middleware
  • Middleware即中间件,上面action是异步的,redux默认是不支持异步action定义,action必须是一个纯的js对象,所以这时候就要使用中间件来解决。
  • 中间件就是一个函数,对store.dispatch方法进行了增强,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。
  • 我们需要使用redux中的applyMiddleware,它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。
  • 使用方法如下:
    const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);
复制代码

2,react-redux

  1. react-redux简介
  • 学习react-redux之前,先来回顾下React和redux。
  • React就是一个状态机,用于构建用户界面的。React本身是有状态管理机制的。定义初始状态,根据状态渲染界面,修改状态是通过setState来实现的。
  • Redux其实是独立的一个状态管理工具,可以在任何地方使用。比如vue、jQuery、原生js、react等等。
  • 我们知道React和Redux是黄金搭档,但是它们又是独立的,那么这时候就需要一个工具把它们联系起来,这个工具就是react-redux。
  • react-redux简单的说就是3个1:
  • (1)一种开发思想---组件分离思想,将组件分成smart(智能)组件和dumb(笨拙)组件。
  • (2)一个connect方法---将dumb组件变成smart组件。
  • (3)一个provider组件---给所有的后代提供store对象。
  1. connect方法
  • react-redux提供了一个connect方法,用于从笨拙组件生成容器组件,connect的意思是将两种组件连接起来。
  • connect()一共有四个参数,我们先说基本的两个,mapStateToProps和mapDispatchToProps。
  • mapStateToProps:简单来说,就是把状态绑定到组件的属性当中。我们定义的state对象有哪些属性,在我们组件的props都可以查阅和获取。使用方法如下:
    const mapStateToProps = (state){
        return{
            counter:state.counter
            //counter是你在哪个组件用的,组件名称
        }
    }
复制代码
  • mapDispatchToProps:用store.dispatch(action)来发出操作,那么我们同样可以把这个方法封装起来,即绑定到我们的方法中。这个方法return的就是一个dispatch函数,将该方法绑定到属性上,我们同样可以在props查看和调用。使用如下:
    const mapDispatchToProps = (dispatch){
        return bindActionCreators(action,dispath)
    }
复制代码
  • 这里将Counter变成智能组件如下:
   connect(mapStateToProps,mapDispatchToProps)(Counter)
复制代码
  1. Provider
  • Provider就是把我们用rudux创建的store传递到内部的其他组件。让内部组件可以享有这个store并提供对state的更新。使用如下:
   ReactDOM.render(
        <Provider store={store}
            <App/>
        <Provider>,
   document.getElementById('root'));
复制代码
  • 其实react-redux中还有许多可用配置的参数和方法。越是复杂的项目,用起来会越清晰。大家一起学习吧!

转载于:https://juejin.im/post/5b77756b6fb9a019d137c2c4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值