• redux详解


    redux介绍

    学习文档英文文档中文文档Github

    redux是什么

    redux是一个独立专门用于做状态管理的JS(不是react插件库),它可以用在react, angular, vue等项目中, 但基本与react配合使用

    作用: 集中式管理react应用中多个组件共享的状态

    redux工作流程

    将会把这个过程比拟成图书馆的一个流程来帮助理解

    Action Creator(具体借书的表达) :想借书的人向图书馆管理员说明要借的书的那句话

    Store(图书馆管理员) :负责整个图书馆的管理。是Redux的核心

    Reducers(图书馆管理员的小本本) :管理员需要借助Reducer(图书馆管理员的小本本)来记录。

    React Component(借书的人 ) :需要借书的人 

    借书的人(ReactComponent)说了一句话(Action Creator)向图书馆管理员(Store)借一本书,可是图书馆管理员年纪大了啊记不住啊,便掏出了自己的小本本(Reducers)。看了看知道了那本书有没有,在哪,怎么样。这样一来管理员就拿到了这本书,再把这本书交给了借书人

    翻译过来就是:组件想要获取State, 用ActionCreator创建了一个请求交给Store,Store借助Reducer确认了该State的状态,Reducer返回给Store一个结果,Store再把这个State转给组件。

    什么情况下需要使用redux

    总体原则: 能不用就不用, 如果不用比较吃力才考虑使用,某个组件的状态,需要共享,某个状态需要在任何地方都可以拿到

    一个组件需要改变全局状态,一个组件需要改变另一个组件的状态

    不用redux的方式实现更改状态

    首先我们创建一个项目,创建应用目录和文件如下

    将创建的main.js组件在App.js入口组件中引入

    import React from 'react';
    import './App.css';
    
    import Main from './views/main/main'
    function App() {
      return (
        <div className="App">
          <Main/>
        </div>
      );
    }
    
    export default App;

    并且在main.js这个组件中实现如下的组件

    import React from 'react';
    import './main.css';
    
    class Main extends React.Component{
      state = {
        count: 0
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
        // 2. 读取原本state中的count状态,并且计算新的count
        const count = this.state.count + number
        // 3. 更新state的count状态
        this.setState({
          count // 完整的写法式count: count,因为名字相同所以直接写一个count即可
        })
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态,并且计算新的count
        const count = this.state.count - number
        // 3. 更新state的count状态
        this.setState({
          count
        })
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.state.count
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 更新state的count状态
          this.setState({
            count: count + number
          })
        }
    
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.state.count
    
        // 启动延时定时器
        setTimeout(() => {
          // 3. 异步更新state的count状态
          this.setState({
            count: count + number
          })
        },1000)
      }
      render() {
        const {count} = this.state
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    export default Main;

    以上我们使用正常的方式实现了上图中的效果,接下来改造成redux的方式去实现,先来看看redux的核心API

    redux的核心API

    store

    就是保存数据的地方,你可以把它看成一个数据,整个应用智能有一个store,Redux提供createStore这个函数,用来生成Store

    state

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

    Action

    state的改变会导致View的变化,但是在redux中不能直接操作state也就是说不能使用this.setState来操作,用户只能接触到View。在Redux中提供了一个对象来告诉Store需要改变state。

    Action是一个对象其中type属性是必须的,表示Action的名称,其他的可以根据需求自由设置。

    store.dispatch( )

    store.dispatch( )是view触发Action的唯一办法,store.dispatch接收一个Action作为参数,将它发送给store通知store来改变state。

    Reducer

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

    redux的基本使用

    首先下载安装redux的依赖包

    npm install --save redux

    项目根目录创建一个专门管理redux的文件夹,并且创建action-types.js文件,用于管理action对象的type常量名称模块

    // action对象的type常量名称模块
    
    export const INCREMENT = 'increment'
    export const DECREMENT = 'decrement'

    然后再redux目录中创建reducer函数的模块:reducers.js

    /*包含n个reducer函数的模块*/
    
    // 根据老的state和指定action, 处理返回一个新的state
    
    import {INCREMENT, DECREMENT} from './action-types'
    
    export function counter(state = 0, action) {
      switch (action.type) {
        case INCREMENT:
          return state + action.data
        case DECREMENT:
          return state - action.data
        default:
          return state
      }
    }

    然后在项目入口文件index.js中引入这个reducer函数counter,并且将这个counter放到createStore方法中返回一个store对象

    store对象的作用是redux库最核心的管理对象,它内部维护着state和reducer,核心方法有getState(),dispatch(action),subscribe(listener)

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    import {createStore} from 'redux';
    import {counter} from './redux/reducers';
    
    // 创建一个store对象
    // createStore()的作用是创建包含指定reducer的store对象
    const store = createStore(counter); // 内部会第一次调用reduer函数得到初始state
    
    console.log(store);//store对象
    
    ReactDOM.render(<App store={store} />, document.getElementById('root'));
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();

    然后在应用组件中使用(需要将store通过props传递到需要使用的组件中)

    import React from 'react';
    import './App.css';
    import PropTypes from 'prop-types'
    
    import Main from './views/main/main'
    class App extends React.Component {
      static propTypes = {
        store: PropTypes.object.isRequired,
      }
    
      render() {
        return (
          <div className="App">
            <Main store={this.props.store}/>
          </div>
        );
      }
    }
    
    export default App;
    import React from 'react';
    import './main.css';
    import PropTypes from "prop-types";
    import {INCREMENT, DECREMENT} from '../../redux/action-types'
    
    class Main extends React.Component{
      static propTypes = {
        store: PropTypes.object.isRequired,
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
    
        // 2. 调用store的方法更新状态
        this.props.store.dispatch({
          type: INCREMENT,
          data: number
        })
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.store.dispatch({
          type: DECREMENT,
          data: number
        })
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.props.store.getState()
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 调用store的方法更新状态
          this.props.store.dispatch({
            type: INCREMENT,
            data: number
          })
        }
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1// 启动延时定时器
        setTimeout(() => {
          // 2. 调用store的方法更新状态
          this.props.store.dispatch({
            type: INCREMENT,
            data: number
          })
        },1000)
      }
      render() {
        const count = this.props.store.getState()
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    export default Main;

    subscribe(listener),状态更新了之后需要调用这个方法来刷新

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    import {createStore} from 'redux';
    import {counter} from './redux/reducers';
    
    // 创建一个store对象
    // createStore()的作用是创建包含指定reducer的store对象
    const store = createStore(counter); // 内部会第一次调用reduer函数得到初始state
    
    console.log(store);//store对象
    
    function render () {
      ReactDOM.render(<App store={store} />, document.getElementById('root'));
    }
    render() // 初始化渲染
    
    store.subscribe(render) // 订阅监听(store中的状态变化了就会自动调用进行重绘)
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();

    可以把要执行的行为对象action单独抽离出来一个模块,使用工厂函数的方式(官方推荐的写法),在redux文件夹中创建一个actions.js

    /*action creator模块*/
    import {INCREMENT, DECREMENT} from './action-types'
    
    export const increment = number => ({type: INCREMENT, data: number})
    export const decrement = number => ({type: DECREMENT, data: number})
    import React from 'react';
    import './main.css';
    import PropTypes from "prop-types";
    import * as actions from '../../redux/actions'
    
    class Main extends React.Component{
      static propTypes = {
        store: PropTypes.object.isRequired,
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
    
        // 2. 调用store的方法更新状态
        this.props.store.dispatch(actions.increment(number))
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.store.dispatch(actions.decrement(number))
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.props.store.getState()
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 调用store的方法更新状态
          this.props.store.dispatch(actions.increment(number))
        }
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 启动延时定时器
        setTimeout(() => {
          // 2. 调用store的方法更新状态
          this.props.store.dispatch(actions.increment(number))
        },1000)
      }
      render() {
        const count = this.props.store.getState()
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    export default Main;

    还有一个就是将store搬到一个独立的模块中,在redux文件夹创建一个store.js的文件

    import {createStore} from 'redux';
    import {counter} from './reducers';
    
    // 创建一个store对象
    // createStore()的作用是创建包含指定reducer的store对象
    const store = createStore(counter); // 内部会第一次调用reduer函数得到初始state
    console.log(store);//store对象
    
    export default store

    修改index.js项目入口文件

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    import store from './redux/store'
    
    function render () {
      ReactDOM.render(<App store={store} />, document.getElementById('root'));
    }
    render() // 初始化渲染
    
    store.subscribe(render) // 订阅监听(store中的状态变化了就会自动调用进行重绘)
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();

    react-redux

    上面使用redux,有一些小的问题就是:reduxreact组件的代码耦合度太高,编码不够简洁,那么就有了一个插件react-redux

    react-redux:一个react插件库,专门用来简化react应用中使用redux

    React-Redux将所有组件分成两大类:

    UI组件:只负责 UI 的呈现,不带有任何业务逻辑,通过props接收数据(一般数据和函数),不使用任何 Redux API,一般保存在components文件夹下

    容器组件:负责管理数据和业务逻辑,不负责UI的呈现,使用 Redux API,一般保存在containers文件夹下

    React-Redux相关API

    Provider:这是一个组件,将这个组件包裹着App.js组件让所有组件都可以得到state数据

    <Provider store={store}>
        <App />
    </Provider>

    connect():用于包装 UI 组件生成容器组件,就是用于react组件和redux之间的连接

    mapStateToprops():将外部的数据(即state对象)转换为UI组件的标签属性

    mapDispatchToProps():将分发action的函数转换为UI组件的标签属性,简洁语法可以直接指定为actions对象或包含多个action方法的对象

    import { connect } from 'react-redux'
    connect(
      mapStateToprops,
      mapDispatchToProps
    )(Counter)

    使用react-redux

    首先需要下载安装依赖包

    npm install --save react-redux

    修改index.js项目入口文件

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    import store from './redux/store'
    import {Provider} from 'react-redux'
    
    ReactDOM.render((
      <Provider store={store} >
        <App/>
      </Provider>
    ), document.getElementById('root'));
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();

    sotre也不需要一层层的传递了

    import React from 'react';
    import './App.css';
    
    import Main from './views/main/main'
    class App extends React.Component {
      render() {
        return (
          <div className="App">
            <Main/>
          </div>
        );
      }
    }
    
    export default App;

    在应用组件中使用react-redux的API方法connect()来跟store进行连接

    import React from 'react';
    import './main.css';
    import PropTypes from "prop-types";
    import { connect } from 'react-redux';
    
    import {increment, decrement} from '../../redux/actions';
    
    class Main extends React.Component{
      static propTypes = {
        count: PropTypes.number.isRequired,
        increment: PropTypes.func.isRequired,
        decrement: PropTypes.func.isRequired
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
    
        // 2. 调用store的方法更新状态
        this.props.increment(number)
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.decrement(number)
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.props.count
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 调用store的方法更新状态
          this.props.increment(number)
        }
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 启动延时定时器
        setTimeout(() => {
          // 2. 调用store的方法更新状态
          this.props.increment(number)
        },1000)
      }
      render() {
        const {count} = this.props
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    // connect是一个函数需要接收一个参数是组件类型(也就是一个对象),执行之后返回的还是一个函数,并且返回新的组件
    export default connect(
      state => ({count: state}),
      {increment, decrement}
    )(Main);

    这样我们就把react-redux给使用上了,还可以在进一步优化就是将connect和组件分离出来,UI组件: 不包含任何redux API

    import React from 'react';
    import './main.css';
    import PropTypes from "prop-types";
    
    class Main extends React.Component{
      static propTypes = {
        count: PropTypes.number.isRequired,
        increment: PropTypes.func.isRequired,
        decrement: PropTypes.func.isRequired
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
    
        // 2. 调用store的方法更新状态
        this.props.increment(number)
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.decrement(number)
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.props.count
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 调用store的方法更新状态
          this.props.increment(number)
        }
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 启动延时定时器
        setTimeout(() => {
          // 2. 调用store的方法更新状态
          this.props.increment(number)
        },1000)
      }
      render() {
        const {count} = this.props
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    export default Main

    创建containters文件夹并且创建一个js文件(包含Main组件的容器组件

    import React from 'react';
    import { connect } from 'react-redux';
    
    import {increment, decrement} from '../redux/actions';
    import Main from '../views/main/main'
    
    // connect是一个函数需要接收一个参数是组件类型(也就是一个对象),执行之后返回的还是一个函数,并且返回新的组件
    export default connect(
      state => ({count: state}),
      {increment, decrement}
    )(Main);
    import React from 'react';
    import './App.css';
    
    import Main from './containters/main'
    class App extends React.Component {
      render() {
        return (
          <div className="App">
            <Main/>
          </div>
        );
      }
    }
    
    export default App;

    这样就完成了react-redux的使用,但是也有一个问题就是redux默认是不能进行异步处理的, 应用中又需要在redux中执行异步任务(ajax, 定时器)

    怎么样让redux支持异步操作,请看下面:redux异步编程

    redux异步编程

    下载redux插件(异步中间件)

    npm install --save redux-thunk

    然后下redux文件夹的store.js文件中引入

    import {createStore, applyMiddleware} from 'redux';
    import thunk from 'redux-thunk';
    import {counter} from './reducers';
    
    // 创建一个store对象
    // createStore()的作用是创建包含指定reducer的store对象
    const store = createStore(
      counter,
      applyMiddleware(thunk)  // 应用上异步中间件
    );
    
    export default store

    在actions.js中添加一个异步操作的方法

    /*action creator模块*/
    import {INCREMENT, DECREMENT} from './action-types'
    
    export const increment = number => ({type: INCREMENT, data: number})
    export const decrement = number => ({type: DECREMENT, data: number})
    export const incrementAsync = number => {
      return dispatch => {
        setTimeout(() => {
          dispatch(increment(number))
        }, 1000)
      }
    }

    在connect()把这个action方法加进来

    import React from 'react';
    import { connect } from 'react-redux';
    
    import {increment, decrement, incrementAsync} from '../redux/actions';
    import Main from '../views/main/main'
    
    // connect是一个函数需要接收一个参数是组件类型(也就是一个对象),执行之后返回的还是一个函数,并且返回新的组件
    export default connect(
      state => ({count: state}),
      {increment, decrement, incrementAsync}
    )(Main);

    在应用组件中通过props进行调用这个action方法

    import React from 'react';
    import './main.css';
    import PropTypes from "prop-types";
    
    class Main extends React.Component{
      static propTypes = {
        count: PropTypes.number.isRequired,
        increment: PropTypes.func.isRequired,
        decrement: PropTypes.func.isRequired,
        incrementAsync: PropTypes.func.isRequired
      }
      increment = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1 // 因为的到的是字符串所以乘以1隐式转换成number
    
        // 2. 调用store的方法更新状态
        this.props.increment(number)
      }
      decrement = () => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.decrement(number)
      }
      incrementIfOdd = ()=> {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
        // 2. 读取原本state中的count状态
        const count = this.props.count
        // 3. 判断当前状态如果式奇数才更新
        if (count%2 === 1) {
          // 4. 调用store的方法更新状态
          this.props.increment(number)
        }
      }
      incrementAsync =() => {
        // 1. 读取select中的值(选择增加的数量)
        const number = this.select.value*1
    
        // 2. 调用store的方法更新状态
        this.props.incrementAsync(number)
      }
      render() {
        const {count} = this.props
        return (
          <div className="App">
            <p>click {count} times</p>
            <div>
              <select ref={select => this.select = select}>
                <option value='1'>1</option>
                <option value='2'>2</option>
                <option value='3'>3</option>
              </select>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
              <button onClick={this.incrementIfOdd}>increment if odd</button>
              <button onClick={this.incrementAsync}>increment async</button>
            </div>
          </div>
        );
      }
    }
    
    export default Main

    使用上redux调试工具

    首先安装chrome浏览器插件(直接在谷歌应用商店搜索,然后点击安装)

    然后在项目中下载工具依赖包

    npm install --save-dev redux-devtools-extension

    修改项目中的创建store的代码中加入这个插件

    import {createStore, applyMiddleware} from 'redux';
    import thunk from 'redux-thunk';
    import { composeWithDevTools } from 'redux-devtools-extension'
    import {counter} from './reducers';
    
    // 创建一个store对象
    // createStore()的作用是创建包含指定reducer的store对象
    const store = createStore(
      counter,
      composeWithDevTools(applyMiddleware(thunk))  // 应用上异步中间件
    );
    
    export default store

    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};
  • 相关阅读:
    从云计算到容器到容器云
    聊聊 CDN 缓存与浏览器缓存
    我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析
    HSTS 详解,让 HTTPS 更安全
    Polaristech 刘洋:基于 OpenResty/Kong 构建边缘计算平台
    Hadoop 2.7.4 HDFS+YRAN HA增加datanode和nodemanager
    hadoop HA学习
    Hadoop 2.7.4 HDFS+YRAN HA部署
    Grafana + Prometheus 监控PostgreSQL
    MySQL 导出用户权限
  • 原文地址:https://www.cnblogs.com/LO-ME/p/10796493.html
Copyright © 2020-2023  润新知