了解 redux 么,说一下 redux 吧

简介: 了解 redux 么,说一下 redux 吧

1、为什么要用redux

React中,数据在组件中是单向流动的,数据从一个方向父组件流向子组件(通过props), 所以,两个非父子组件之间通信就相对麻烦,redux的出现就是为了解决state里面的数据问题

2、Redux设计理念

Redux是将整个应用状态存储到一个地方上称为store, 里面保存着一个状态树store tree, 组件可以派发(dispatch)行为(action)给store, 而不是直接通知其他组件,组件内部通过订阅store中的状态state来刷新自己的视图。

3、Redux三大原则

1.唯一数据源

整个应用的state都被存储到一个状态树里面,并且这个状态树,只存在于唯一的store中

2.保持只读状态

state是只读的,唯一改变state的方法就是触发action,action是一个用于描述以发生时间的普通对象

3.数据改变只能通过纯函数来执行

使用纯函数来执行修改,为了描述action如何改变state的,你需要编写reducers

4、Redux概念解析

1.Store

  • store就是保存数据的地方,你可以把它看成一个数据,整个应用只能有一个store
  • Redux提供createStore这个函数,用来生成Store
import {
    createStore
} from 'redux'
const store = createStore(fn);

2.State

state就是store里面存储的数据,store里面可以拥有多个state,Redux规定一个state对应一个View, 只要state相同,view就是一样的,反过来也是一样的,可以通过store.getState( )获取

import {
    createStore
} from 'redux'
const store = createStore(fn);
const state = store.getState()

3.Action

state的改变会导致View的变化,但是在redux中不能直接操作state也就是说不能使用this.setState来操作,用户只能接触到View。在Redux中提供了一个对象来告诉Store需要改变state。Action是一个对象其中type属性是必须的,表示Action的名称,其他的可以根据需求自由设置。

const action = {
    type: 'ADD_TODO',
    payload: 'redux原理'
}

在上面代码中,Action的名称是ADD_TODO,携带的数据是字符串‘redux原理’,Action描述当前发生的事情,这是改变state的唯一的方式

4.store.dispatch( )

store.dispatch( )是view发出Action的唯一办法

store.dispatch({
    type: 'ADD_TODO',
    payload: 'redux原理'
})

store.dispatch接收一个Action作为参数,将它发送给store通知store来改变state。

5.Reducer

Store收到Action以后,必须给出一个新的state,这样view才会发生变化。这种state的计算过程就叫做Reducer。 Reducer是一个纯函数,他接收Action和当前state作为参数,返回一个新的state

注意:Reducer必须是一个纯函数,也就是说函数返回的结果必须由参数state和action决定,而且不产生任何副作用也不能修改state和action对象

const reducer = (state, action) => {
    switch (action.type) {
        case ADD_TODO:
            return newstate;
        default
        return state
    }
}

5、Redux源码

let createStore = (reducer) => {
    let state;
    //获取状态对象
    //存放所有的监听函数
    let listeners = [];
    let getState = () => state;
    //提供一个方法供外部调用派发action
    let dispath = (action) => {
        //调用管理员reducer得到新的state
        state = reducer(state, action);
        //执行所有的监听函数
        listeners.forEach((l) => l())
    }
    //订阅状态变化事件,当状态改变发生之后执行监听函数
    let subscribe = (listener) => {
        listeners.push(listener);
    }
    dispath();
    return {
        getState,
        dispath,
        subscribe
    }
}
let combineReducers = (renducers) => {
    //传入一个renducers管理组,返回的是一个renducer
    return function(state = {}, action = {}) {
        let newState = {};
        for (var attr in renducers) {
            newState[attr] = renducers[attr](state[attr], action)
 
        }
        return newState;
    }
}
export {
    createStore,
    combineReducers
};

6、Redux使用案例

html代码

<div id="counter"></div>
<button id="addBtn">+</button>
<button id="minusBtn">-</button>

js代码

function createStore(reducer) {
    var state;
    var listeners = [];
    var getState = () => state;
    var dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(l => l());
    }
    var subscribe = (listener) => {
        listeners.push(listener);
        return () => {
            listeners = listeners.filter((l) => l != listener)
        }
    }
    dispatch();
    return {
        getState,
        dispatch,
        subscribe
    }
}
var reducer = (state = 0, action) => {
    if (!action) return state;
    console.log(action);
    switch (action.type) {
        case 'INCREMENT':
            return state + 1;
        case 'DECREMENT':
            return state - 1;
        default:
            return state;
    }
}
var store = createStore(reducer);
store.subscribe(function() {
    document.querySelector('#counter').innerHTML = store.getState();
});
 
document.querySelector('#addBtn').addEventListener('click', function() {
    store.dispatch({
        type: 'INCREMENT'
    });
});
document.querySelector('#minusBtn').addEventListener('click', function() {
    store.dispatch({
        type: 'DECREMENT'
    });
});


相关文章
|
JavaScript 前端开发 中间件
useReducer+createContext真的可以代替Redux吗?
useReducer+createContext真的可以代替Redux吗?
166 0
|
4月前
|
JavaScript 前端开发 中间件
像Vuex一样使用redux
【8月更文挑战第16天】像Vuex一样使用redux
31 2
像Vuex一样使用redux
|
4月前
|
存储 JavaScript 前端开发
什么是 Redux?
【8月更文挑战第30天】
54 0
|
存储 JavaScript 前端开发
什么是Redux?
什么是Redux?
|
JavaScript 中间件
React-Redux-thunk
React-Redux-thunk
48 0
|
存储 JavaScript 中间件
React-Redux-Saga
React-Redux-Saga
30 0
|
JavaScript
Redux中 combineReducers的使用
Redux中 combineReducers的使用
|
JavaScript 前端开发 中间件
说说你对Redux的理解?和react-redux有什么区别?
说说你对Redux的理解?和react-redux有什么区别?
|
JavaScript 前端开发
什么是redux?如何在react 项目中使用redux?
什么是redux?如何在react 项目中使用redux?
107 0
|
存储 JavaScript 前端开发
MobX or Redux ? #81
MobX or Redux ? #81
89 0