Redux与纯JS入门实例讲解

来源:互联网 发布:忘记root密码 linux 编辑:程序博客网 时间:2024/06/09 15:37

Redux与纯JS入门实例讲解

学习Redux可能是一个噩梦,我猜应该每个人都读过那篇”You Might Not Need Redux”然后扔掉了手中的电脑。如果一来就是npm install --save react-redux,你很可能在做了几个TodoList之类的例程之后还是不甚清楚redux究竟是做什么的,或者没那么清楚。或许,你需要的仅仅是一个不包含react的redux例子。

redux和react是什么关系

react和redux之间没有关系。

redux支持react、Angular、Ember、JQuery以及纯JS等。redux和react框架搭配起来很好用,但并不意味着学习redux的第一步就是安装React绑定库:

npm install --save react-redux

可能先看看redux对纯JS的支持更有利于理解redux。

准备工作

准备工作十分简单,你不需要安装任何依赖,不需要包管理工具,不需要模块打包工具甚至你根本就不需要模块。

打开你最喜欢的文本编辑器,将下面的HTML代码粘贴进去就可以了。

<!DOCTYPE html><html>  <head>    <title>Redux basic</title>    <script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>  </head>  <body>  </body></html>

这里通过<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>引入了预编译好的Redux文件。

直接在浏览器打开上面的html文件然后在控制台通过全局变量window.Redux即可访问Redux对象。

可以看到其对象方法:

简单的例子

在上面的html代码中完善以下代码,一个简单的redux例子就完成了。

<!DOCTYPE html><html>  <head>    <title>Redux basic</title>    <script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>  </head>  <body>    <div>      <p><span id="colorEl">Watch my color.</span>         <button id="red">RED</button>         <button id="green">GREEN</button>         <button id="toggle">TOGGLE</button>    </div>    <script type="text/javascript">        var initialState = {            color: 'red'        }        function color(state, action) {            if(typeof state === 'undefined') {                return initialState            }            switch(action.type) {                case 'RED' :                     return { color: 'red'}                case 'GREEN' :                     return { color: 'green'}                case 'TOGGLE' :                    return state.color === 'red' ? {color:'green'} : {color:'red'}                default :                    return state            }        }        var store = Redux.createStore(color)        var colorEl = document.getElementById('colorEl')        function renderValue() {            colorEl.style.color = store.getState().color        }        renderValue()        //注册监听器        store.subscribe(renderValue)        document.getElementById('red').addEventListener('click', function(){            store.dispatch({                type: 'RED'            })        })        document.getElementById('green').addEventListener('click', function(){            store.dispatch({                type: 'GREEN'            })        })        document.getElementById('toggle').addEventListener ('click', function(){          store.dispatch({            type: 'TOGGLE'          })        })    </script>>  </body></html>

现在在浏览器打开以上html文件,试着点击里面的按钮。这就是redux在原生js中的使用。

Redux基本概念

下面结合以上简单的例子说明redux中几个基本的概念。

1、单一数据源

Redux中只有单一数据源,整个应用的所有state都被存储在一个单一的对象中。在本例中,我们只维护了一个state也就是<span id="colorEl">Watch my color.</span>的颜色属性,因此该对象中也只有一个属性:

var initalState = {  color: 'red'}

这是最简单的例子,当应用变得复杂的时候,我们需要首先根据应用的所有state思考设计一下这个对象的结构,但这里我们暂时不关心这个问题。

2、使用action改变应用的state

当我们需要改变应用的state的时候,不能直接修改state值,Redux中的state是只读的。

唯一改变state的方法就是触发一个action,action是一个普通的JavaScript对象,用来描述发生了什么。每个action对象都要有一个type属性,你可以理解为是唯一标识这个action的名字。

在本例中,我们给三个按钮#red,#green,#toggle分别绑定了click事件,每当点击的时候分别触发一个action,注意代码中的以下部分:

store.dispatch({    type: 'RED'})store.dispatch({    type: 'GREEN'})store.dispatch({    type: 'TOGGLE'})

store.dispatch方法中分别传入了三个对象(后面说明store.dispatch是什么)

{ type: 'RED'}{ type: 'GREEN'}{ type: 'TOGGLE'}

就是action,type是唯一标识他们类型的名字。action是一个用来描述发生了什么的对象,以上3个action不妨理解成发生了“变红”,“变绿”或者“切换颜色”的事情。

3、使用Reducer来执行对state的修改

action是一个普通的JavaScript对象,它用来描述发生了什么,但它并不描述发生的这个事情该怎么去修改state,如何根据action去修改state是Reducer的事情。

Reducer是什么,它就是一个纯函数,接收旧的state以及action作为输入参数,返回新的state。

在本例中就是下面这个函数:

function color(state, action) {    if(typeof state === 'undefined') {        return initialState    }    switch(action.type) {        case 'RED' :             return { color: 'red'}        case 'GREEN' :             return { color: 'green'}        case 'TOGGLE' :            return state.color === 'red' ? {color:'green'} : {color:'red'}        default :            return state    }}

Reducer决定了如何修改state,当action的type是’RED’的时候返回一个新的state其中color属性的值为’red’,当action的type是’GREEN’的时候返回一个新的state其中color属性的值为’green’,’TOGGLE’同理。

关于Reducer请注意:

  • 不要修改state的值,请返回一个新的副本;
  • 在遇到未知action时,默认情况下一定要返回旧的state;

另外请大家注意,上面的{ type: ‘RED’}对象从语义上来说是将<span id="colorEl">Watch my color!</span>变红,但要明白,这仅仅是语言的含义,至于针对这个action如何处理state那是Reducer决定的,你当然可以在触发{ type: ‘RED’}的时候将<span id="colorEl">Watch my color!</span>变绿或者甚至删掉。牢牢记住,action只是描述发生了什么,Reducer决定针对这个action做什么处理。

4、store

store是一个对象,使用Redux提供的createStore方法来生成,我们需要将Reducer作为参数传进去,在本例中:

//Reducerfunction color(state, action) {    if(typeof state === 'undefined') {        return initialState    }    switch(action.type) {        case 'RED' :             return { color: 'red'}        case 'GREEN' :             return { color: 'green'}        case 'TOGGLE' :            return state.color === 'red' ? {color:'green'} : {color:'red'}        default :            return state    }}var store = Redux.createStore(color)

store拥有以下方法:

  • 通过store.getState()方法来获取state;
  • 通过store.dispatch(action)方法来更新state;
  • 通过subscribe(listener)方法来注册监听器,state变化时自动执行该函数;

本例中:

通过store.getState()获取state,并根据state值来设置colorEl的颜色属性:

function renderValue() {    colorEl.style.color = store.getState().color}

通过store.subscribe()来注册监听器,每当state发生变化时执行上面的函数:

//注册监听器store.subscribe(renderValue)

通过store.dispatch(action)来触发修改state的操作,写在事件处理程序中,点击按钮时修改state:

document.getElementById('red').addEventListener('click', function(){    store.dispatch({        type: 'RED'    })})document.getElementById('green').addEventListener('click', function(){    store.dispatch({        type: 'GREEN'    })})document.getElementById('toggle').addEventListener ('click', function(){    store.dispatch({        type: 'TOGGLE'    })})

总结

应用中所有的state都以一个object tree的形式存储在唯一一个store中,想要改变state的唯一方式是触发一个action,action只用来描述发生了什么,编写reducer来根据action去改变应用的state。

首先理解这一点再深入学习redux以及redux配合react的使用是不是会轻松一些?

欢迎关注我的主页

1 0