Redux

作者: 丶HanGH | 来源:发表于2017-12-08 21:06 被阅读0次

    Redux

    专注于状态管理的库

    1. Redux专注于状态管理和react解耦
    2. 单一状态,单向数据流
    3. 核心概念:store,state,action,reducer

    使用

    1. 安装
      npm install redux --save
    2. 基础使用
    import {createStore} from 'redux';
    
    //新建store
    //通过reducer建立
    //根据老的state和action 生成新的state
    function counter(state = 0, action) {
        switch (action.type) {
            case '赚了1块钱':
                return state + 1;
            case '花了1块钱':
                return state - 1;
            default:
                //初始状态
                return 10;
        }
    }
    
    const store = createStore(counter);
    
    console.log("开始手里有" + store.getState() + "块钱");
    
    
    function listenner() {
        const current = store.getState();
        console.log(`现在手里有${current}块钱`);
    }
    
    //订阅,每次状态更换都会触发linstenner函数
    store.subscribe(listenner);
    //派发事件 传递action
    store.dispatch({
        type: '赚了1块钱'
    });
    store.dispatch({
        type: '赚了1块钱'
    });
    store.dispatch({
        type: '赚了1块钱'
    });
    
    运行结果

    Redux 和 React 一起使用

    1. 把store.dispatch方法传递给组件,内部可以调用修改状态。
    2. Subscribe订阅render函数,每次修改都重新渲染。
    3. Redux相关内容,移到单独的文件index.redux.js单独管理。
    index.js
    import React from 'react';
    import ReactDom from 'react-dom';
    import {createStore} from 'redux';
    import {counter} from './index.redux';
    import App from './App';
    
    //创建store
    const store = createStore(counter);
    function render() {
        ReactDom.render(
            <App store = {store} />,
            document.getElementById('root')
        );
    }
    render();
    //重新渲染render
    store.subscribe(render);
    
    index.redux.js
    const makeMoney = "赚了1块钱";
    const spendMoney = "花了1块钱";
    
    //状态管理
    export function counter(state = 0, action) {
        switch (action.type) {
            case makeMoney:
                return state + 1;
            case spendMoney:
                return state - 1;
            default:
                //初始状态
                return 10;
        }
    }
    
    //action creator 创建action
    export function MakeMoney() {
        return {type:makeMoney}
    }
    export function SpendMoney() {
        return {type:spendMoney}
    }
    
    App.js
    import React, {Component} from 'react';
    import {
        Button
    } from 'antd-mobile';
    
    export default class App extends Component {
        // constructor(props){
        //     super(props);
        // }
        render() {
            //属性获取可以直接用
            const store = this.props.store;
            //获取当前状态
            const money = store.getState();
            //获取方法
            const MakeMoney = this.props.MakeMoney;
            const SpendMoney = this.props.SpendMoney;
            return (
                <div>
                    <h1 align='center'>现在手里有{money}块钱</h1>
                    <Button type='primary' onClick={() => store.dispatch(MakeMoney())}>赚钱</Button>
                    <br/>
                    <Button type='primary' onClick={() => store.dispatch(SpendMoney())}>花钱</Button>
                </div>
            )
        }
    }
    
    运行结果

    处理异步、调试工具、更优雅的和react结合

    处理异步

    1. redux-thunk插件
      npm install redux-thunk --save
    2. index.js添加和修改代码
    //增加applyMiddleware模块
    import {createStore,applyMiddleware} from 'redux';
    //引入thunk
    import thunk from 'redux-thunk';
    
    1. index.redux.js添加函数
    export function MakeMoneyAsync() {
        return dispatch=>{
            setTimeout(()=>{
                dispatch(MakeMoney());
            },2000);
        };
    }
    

    2.使用applyMiddleware开启thunk中间件

    1. Action可以返回函数,使用dispatch提交action

    调试工具

    1. 在chrome安装Redux调试工具
      Redux DevTools
    2. 使用
      - 新建store的时候判断window.devToolsExtension
      - 使用compose结合thunk和window.devToolsExtension
      - 开发者工具中的Redux选项卡下可以看到实时state
    3. 代码修改index.js文件
    import React from 'react';
    import ReactDom from 'react-dom';
    //增加applyMiddleware模块
    import {createStore,applyMiddleware,compose} from 'redux';
    //引入thunk
    import thunk from 'redux-thunk';
    import {counter,MakeMoney,SpendMoney,MakeMoneyAsync} from './index.redux';
    import App from './App';
    
    //修改代码判断系统是否存在函数,若没有则返回空
    const ReduxDevTools = window.devToolsExtension?window.devToolsExtension():f=>f;
    //创建store
    const store = createStore(counter,compose(
        applyMiddleware(thunk),
        ReduxDevTools
    ));
    
    function render() {
        ReactDom.render(
            <App store = {store} MakeMoney={MakeMoney} SpendMoney={SpendMoney} MakeMoneyAsync={MakeMoneyAsync}/>,
            document.getElementById('root')
        );
    }
    render();
    //订阅render函数,状态变化重新渲染
    store.subscribe(render);
    
    1. 运行结果


    使用react-redux优雅的链接react和redux

    1. 安装
      npm install react-rudex --save
    2. 具体使用
      • Provide组件在应用最外层,传入store即可,只用一次
      • Connect负责从外部获取组件需要的参数
      • Connect可以用装饰器的方式来写
    3. 修改后的代码
    //index.js
    import React from 'react';
    import ReactDom from 'react-dom';
    //增加applyMiddleware模块
    import {createStore, applyMiddleware, compose} from 'redux';
    //引入thunk
    import thunk from 'redux-thunk';
    //引入Provider组件
    import {Provider} from 'react-redux';
    import {counter} from './index.redux';
    import App from './App';
    
    //创建store
    const store = createStore(counter, compose(
        applyMiddleware(thunk),//创建异步Redux
        //引入Chrome中的Redux开发者工具
        //修改代码判断系统是否存在函数,若没有则返回空
        window.devToolsExtension ? window.devToolsExtension() : f => f
    ));
    //最外层使用Provide组件,属性只传store,内部App组件内不需要任何属性
    ReactDom.render(
        (<Provider store={store}>
            <App/>
        </Provider>),
        document.getElementById('root')
    );
    
    //App.js
    import React, {Component} from 'react';
    import {
        Button
    } from 'antd-mobile';
    //引入connect专门用来连接
    import { connect } from 'react-redux';
    //引入动作
    import {
        MakeMoneyAsync,
        MakeMoney,
        SpendMoney
    } from './index.redux';
    
    class App extends Component {
        render() {
            return (
                <div>
                    <h1 align='center'>现在手里有{this.props.money}块钱</h1>
                    <Button type='primary' onClick={this.props.MakeMoney}>赚钱</Button>
                    <br/>
                    <Button type='primary' onClick={this.props.SpendMoney}>花钱</Button>
                    <br/>
                    <Button type='primary' onClick={this.props.MakeMoneyAsync}>过了2秒又赚钱</Button>
                </div>
            )
        }
    }
    //使用connect装饰器
    const mapStatetoProps = (state) => {
        return {money: state};
    };
    const actionCreators = {
        MakeMoneyAsync,
        MakeMoney,
        SpendMoney
    };
    //传递属性和方法
    App = connect(mapStatetoProps,actionCreators)(App);
    export  default App;
    

    使用装饰器优化connect

    1. 弹出配置文件
      npm run eject
    2. 使用插件
      npm install babel-plugin-transform-decorators-legacy --save-dev
    3. 在package.json中加上plugins配置
      在babel下的plugins内添加
       [
            "transform-decorators-legacy"
       ]
    
    1. 代码修改 App.js
    //使用connect装饰器
    // const mapStatetoProps = (state) => {
    //     return {money: state};
    // };
    // const actionCreators = {
    //     MakeMoneyAsync,
    //     MakeMoney,
    //     SpendMoney
    // };
    //传递属性和方法
    //App = connect(mapStatetoProps,actionCreators)(App);
    //删除上面代码并改为如下
    //将@connect挪到class上面
    @connect(
        //需要的属性
        state=>({money:state}),
        //需要的方法,自动dispatch
        { MakeMoneyAsync, MakeMoney, SpendMoney}
    )
    export default class App extends Component {
          ...
    }
    

    相关文章

      网友评论

          本文标题:Redux

          本文链接:https://www.haomeiwen.com/subject/bevlixtx.html