Redux介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux介绍相关的知识,希望对你有一定的参考价值。

Redux 有三个基本的原则:

  1,单一状态树,redux 只使用一个javascript 对象来保存整个应用的状态。 状态树样式如下:

const state = {
     count: 0
}

  2,状态是只读的,不是说不能修改state,只是我们不能直接修改state, 那么怎样才要可以改state呢? 修改state的唯一方法是发送一个action,action也很简单,就是一个JavaScript 对象,它描述了我们将要对state作什么样的变化。 如下:

{
    type: ‘MINUS‘
}

  type: 就是描述了我们将要对状态state执行什么样的操作,在这里是做减法操作。当然,这是最简单的action, 你可以构建任意复杂的action,  因为它只是一个普通的JavaScript对象, 所以除了必须的type字段外,我们可以构建任何想要的字段。如

{
  type: ADD_TODO,
  text: ‘Build my first Redux app‘
}

  我们发送了一个action,表示我们想要更改state, 那要在什么地方去改变我们的state,那就是reducer 应该做的事情了。 reducer 就是一个纯函数,它接受state, 和action 作为参数,然后返回一个新的state. 接受state, action 两个参数,就表示它可以根据action去改变state, 这里一定要注意,它一定是返回一个新的state,不要去改变原state的状态

function counterReducer(state, action) {  
    switch (action.type){
        case ‘ADD‘: 
            return state + 1; 
        default: 
            return state;
    }
}

  有了state,action, reducer,它们是怎么串联起来的,那就是store。

  首先,我们整个应用的状态就是存储在store中,由store来维持整个应用的状态。其次它提供了store.dispatch 来发起action, 发起一个action后,提供了subscribe 监听这个action带来的状态的变化,状态发生变化后,它提供了getState() 来获取更新的state. 那怎么创建store, redux 提供了一个createStore方法,它接收reducer作为参数,返回store, 它还可以接受一个可选的state, 作为默认初始值。

  你可以看到redux执行的是单向数据流,发送一个action给store, store 就会把当前的state和action传递给reducer, reducer 会计算出一个新的状态,通过store.getState()获取到最新的状态。

 

   现在写一个加减项目来体验一下redux. 页面中有三个按钮,一个加,一个减和一个重置,还有一个h1 显示结果。在文件夹中新建一个index.html,一个counter.js 和一个counter.css文件

  整个html代码如下:head 中引入css 和redux,  body中就是三个按钮,和一个h1

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Redux</title>
  <link rel="stylesheet" href="./counter.css">
  <script src="https://cdn.bootcss.com/redux/3.7.2/redux.js"></script>
</head>
<body>
  <div class="container">
    <h1 id="counter">0</h1>
    <button class="btn btn-blue" id="add">Add</button>
    <button class="btn btn-green" id="minus">Minus</button>
    <button class="btn btn-red" id="reset">Reset</button>
  </div>
  <script src="./counter.js"></script>
</body>
</html>

  counter.css 文件如下:

body {
    padding: 40px;
    font-family: "helvetica neue", sans-serif;
  }
  
  .container {
    width: 600px;
    margin: auto;
    color: black;
    padding: 20px;
    text-align: center;
  }
  .container h1 {
    margin: 0;
    padding: 20px;
    font-size: 48px;
  }
  .container .btn {
    border: 0;
    padding: 15px;
    margin: 10px;
    width: 20%;
    font-size: 15px;
    outline: none;
    border-radius: 3px;
    color: #FFF;
    font-weight: bold;
  }
  
  .btn.btn-blue {
    background-color: #55acee;
    box-shadow: 0px 5px 0px 0px #3C93D5;
  }
  
  .btn.btn-blue:hover {
     background-color: #6FC6FF;
  }
  
  .btn.btn-green {
    background-color: #2ecc71;
    box-shadow: 0px 5px 0px 0px #15B358;
  }
  
  .btn.btn-green:hover {
    background-color: #48E68B;
  }
  
  .btn.btn-red {
    background-color: #d84a4a;
    box-shadow: 0px 5px 0px 0px #a73333;
  }
  
  .btn.btn-red:hover { 
    background-color: #f15656;
  }

  在页面中的效果如下:

技术分享

 

   现在我们来写counter.js 文件,就是如何使Redux 

  1, 首先我们要创建store, 那创建store之前 就要先定义state, reducer. 我们的state 非常简单, 就是一个count, 来展示数字

const state = {count: 0};

  2, 创建reducer. 在这个简单的小例子中,我们有三个action, 当点击Add按钮时,它会发送ADD, 相应的count就会加1, 当点击Minus按钮时,它会发送MINUS, 相应的count 就会减1. 当点击Reset, 它会发送RESET, 相应的count置为0;  所以在reducer中我们要处理3个action,  相应的返回3个state,  

function counterReducer(state, action) {
     // reducer 都会返加一个全新的state, 所以在这里声明了一个新的变量nextState,代表一个新的状态,用于返回
    var nextState = {
        count: state.count
    }
    switch (action.type){
        case ‘ADD‘:         // ADD action, count 加1, 
            nextState.count = state.count + 1;
            return nextState; 
        case ‘MINUS‘:       // MINUS action, count 减1
            nextState.count = state.count - 1;
            return nextState;  
        case ‘RESET‘:       // RESET action, count 置为0
            nextState.count = 0;
            return nextState;
        default:            // 当发送一个未知action时的后退处理
            return state;
    }
}

  在设置reducer时,一定要注意:

    1, 它是一个纯函数,返回一个新的状态;

    2,  在switch case 语句中,一定要提供default, 返回当前状态

  3, 现在有了state 和 reducer,可以创建store 了。

const store = Redux.createStore(counterReducer, state);  // 创建store

  4, 我们要在点击按钮时更改状态,那就要发送action 

// Add 按钮发送ADD action
document.getElementById(‘add‘).addEventListener(‘click‘, function(){
    store.dispatch({type: ‘ADD‘})
})
// Minus按钮发送MINUS action
document.getElementById(‘minus‘).addEventListener(‘click‘, function() {
    store.dispatch({type: ‘MINUS‘})
})
// Reset按钮发送RESET action
document.getElementById(‘reset‘).addEventListener(‘click‘, function() {
    store.dispatch({type: ‘RESET‘})
})

  5, 发送action 之后, state就会发生变化,我们页面中怎么获取到最新的状态进行展示?那就要订阅这个action事件,以便state 发生变化后,我们能及时更新state, 用到store.subscribe 函数, 它接受一个函数,只要有action发生,状态改变,它接受的回调函数就会触发。 我们可以在store.subscribe接受的函数中,获取store中的最新状态,获取最新状态,是用store.getState() 方法。 首先写一个render方法,获取最新的state, 然后给页面中的h1赋值。然后把render 方法传递给store.subscribe

const counterEl = document.getElementById(‘counter‘);

// render 函数获取状态,并给页面赋值
function render() {
    var state =  store.getState();  // 获取状态
    counterEl.innerHTML = state.count.toString();
}

// 订阅action, 以便action触发state, 状态发生变化后我们能及时得到通知,获取最新的state.
store.subscribe(render);

  6, 现在点击Add 按钮,就可以看到页面中在不停的加1, 点击Minus,不停地减1,而点击Reset, 页面上会显示0。

  

以上是关于Redux介绍的主要内容,如果未能解决你的问题,请参考以下文章

P19:Redux进阶-React-Redux介绍和安装

Redux工具包 - Redux Toolkit的基本使用

提供商无法访问redux商店

Relay 和 redux - initialVariables

将状态传递给 React/Redux 中的递归嵌套组件

React-Redux-实现原理