Redux与纯JS入门实例讲解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a153375250/article/details/53374081

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作为参数传进去,在本例中:

//Reducer
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)

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的使用是不是会轻松一些?

欢迎关注我的主页

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页