最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Redux、React和Redux配合、logger | 8月更文挑战

    正文概述 掘金(木子又又又又)   2021-08-27   545

    这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

    Redux

    官网:redux.js.org/

    创建一个Redux项目用Nodejs调试

    创建身份证

    npm init
    

    安装依赖

    npm install --save redux
    

    创建app.js

    var redux = require("redux");
    
    //创建一个函数,叫做reducer。
    const reducer = (state = {"a" : 10} , action) => {
        if(action.type == "ADD"){
            return {
                "a" : state.a + 1
            }
        }else if(action.type == "MINUS"){
            return {
                "a" : state.a - 1
            }
        } else if (action.type == "PINGFANG") {
            return {
                "a" : state.a * state.a
            }
        }
        return state;
    }
    
    //根据reducer函数创建store
    const store = redux.createStore(reducer);
    
    //得到store中的a
    console.log(store.getState().a);
    
    //发出ADD命令
    store.dispatch({"type" : "ADD"}); //10+1
    store.dispatch({"type" : "ADD"}); //11+1
    store.dispatch({"type" : "ADD"}); //12+1
    
    //得到store中的a
    console.log(store.getState().a); //13
    
    //发出减法命令
    store.dispatch({"type" : "MINUS"});  // 13-1
    
    //得到store中的a
    console.log(store.getState().a); // 12
    
    store.dispatch({ "type": "PINGFANG" }); //12*12
    //得到store中的a
    console.log(store.getState().a); //144
    

    当dispatch 发出后 store变化了,而试图没有更新,需要使用订阅subscribe方法

    1、 在组件内的 componentDidMount 声明周期内 强制刷新

    componentDidMount(){
        store.subscribe(()=>{
          this.forceUpdate()
        })
    }
    

    2、在入口文件中配置 subscribe,订阅后 重新 执行render

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import store from './store'
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    )
    
    store.subscribe(()=>{
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      )
    })
    

    使用redux 检查点

    1. createStore 创建store
    2. reducer 初始化、修改状态函数
    3. getState 获取状态值
    4. dispatch 提交更新
    5. subscribe 变更订阅

    可预测状态容器

    借助Redux,你可以控制状态改变的时间、原因和方式。

    Store: 单一数据源

    步骤:引入createStore函数、引入reducer统领文件、创建store、试着弹出一个a。

    store有下面的责任:
    持有app的state允许通过getState()得到state允许通过dispatch来改变state只能有1个store在你的app中。当你想切分你的数据逻辑,你应该考虑拆分reducer而不是拆分store。创建一个reducer很简单,使用combineReducers()可以轻松合并多个reducer到一个。并且传入createStore()中

    得到Store的State的值,需要使用store.getState().a

    复杂的state

    state 可能是复杂的结构,此时写在行内不好看,可以提炼为变量(常量)

    var redux = require("redux");
    
    //初始state
    const initState = {
        students : [
            {"id": 1, "name": "小明" , "age" : 12},
            {"id": 2, "name": "小强" , "age" : 14},
            {"id": 3, "name": "小钢炮" , "age" : 13}
        ]
    }
    
    //reducer
    const reducer = (state = initState, action) => {
        .........
        .........
    }
    

    reducer 纯函数

    记住4个no:
    No surprises. No side effects. No API calls. No mutations. Just a calculation.没有惊喜、没有副作用、没有API调用、没有改变传入的参数。就是一个计算。

    纯函数是函数式编程的概念,必须遵守以下一些约束:

    • 不得改写参数
    • 不能调用写I/O的API
    • 不能调用Date.now() 或者Math.random()等不纯的方法,因为每次得到不一样的结果

    Reducer是纯函数,就可以保证同一的state,必定得到同样的View,Reducer函数里面不能改变State,必须返回一个全新的对象。

    一个函数会有很多reducer,所以要有一个index.js作为“统领文件”

    dispatch和action

    store.disptch()

    action

    • Action就是一个信息的载荷体,从APP(逻辑层、视图层)送到你的store中(数据层)。
    • action是store唯一的信息的来源。
    • action需要被dispatch()函数派发。
    • action是纯的、扁平的JavaScript对象。
    • action必须有一个type属性,type属性指示了这个action是干嘛的。

    action就是一个有type属性的JSON:

    {"type" : "ADD"}
    

    payload 载荷

    action不仅有type属性,其他的属性,叫做载荷(payload)

    combineReducers 合并多个reducer

    注意:

    • 访问值的时候,多个一个命名空间
    • 改变值的时候,没有命名空间
    //要合并reducer,因为任何项目只能有一个reducer。
    const reducer = redux.combineReducers({
        counterReducer ,
        studentReducer
    });
    
    //store,不管项目有多大,一定只有一个store
    const store = redux.createStore(reducer);
    
    //注意,访问值的时候,多了一个命名空间
    console.log(store.getState().counterReducer.a);
    
    //但是,改变值的时候,没有命名空间
    store.dispatch({ "type" : "ADD"});
    store.dispatch({ "type" : "ADD"});
    store.dispatch({ "type" : "ADD"});
    
    //注意,访问值的时候,多了一个命名空间
    console.log(store.getState().counterReducer.a);
    

    React和Redux配合使用

    所有的数据要保存在store中

    Redux、React和Redux配合、logger | 8月更文挑战

    配置和使用

    1. 先配置好webpack+react那一套 安装依赖
    npm install --save redux
    npm install --save react-redux
    
    • react-redux 是官方的“粘合剂”
      • 这个粘合剂就提供了两个东西:Provider组件、connect函数。
    1. Provider from react-redux

    main.js

    import React from "react";
    import ReactDOM from "react-dom";
    import {createStore} from "redux";
    import {Provider} from "react-redux";
    
    import App from "./App";
    import reducer from "./reducers";
    
    //创建store
    const store = createStore(reducer);
    
    
    ReactDOM.render(
        <Provider store={store}>
            <App></App>
        </Provider>
        ,
        document.getElementById("app")
    );
    

    app.js

    • import { connect } from "react-redux"
    import React, { Component } from 'react';
    import { connect } from "react-redux";
    
    class App extends Component {
        constructor(){
            super();
        }
        render() {
            return (
                <div>
                    <h1>根组件{this.props.a}</h1>
                    <button onClick={()=>{
                        this.props.add();
                    }}>按我加1</button>
                </div>
            )
        }
    }
    //connect 函数 有两个参数和需要连接的组件App
    export default connect(
        ({counterReducer}) => ({
            a : counterReducer.a
        }),
        (dispatch) => ({
            add(){
                dispatch({"type" : "ADD"})
            }
        })
    )(App);
    

    Provider

    • Provider 是组件,在main.js入口文件中用一次
    • connect 是函数,哪个组件要“通天”要数据,哪个组件就要connect装饰一下。
    • Provider的机理是使用context上下文机理。

    Provider使用起来很简单,引包之后,包裹app,注意store属性:

    import {Provider} from "react-redux";
    
    ReactDOM.render(
        <Provider store={store}>
            <App></App>
        </Provider>
        ,
        document.getElementById("app")
    );
    

    connect装饰器

    语法:

    connect(mapStateToProps , mapDispatchToProps)(类名字)
    
    • 组件要更新视图,只有两种手段:
      • 组件自己的state改变
      • 传入组件的props改变
    • 全局store数据变化了,组件视图要更新。
    • store中的数据,要被“装饰”到组件上,成为组件的props。

    组件要被connect()()装饰一下,才能暴露:

    • 第一个()内写如何装饰,第二个()内写装饰谁。
      • 第一个()有两个参数 mapStateToProps和mapDispatchToProps

    mapStateToProps(state, ownProps)

    • mapStateToProps 是一个函数,用于建立组件跟store的state的映射关系,它传入两个参数,结果一定返回一个object。
    • mapStateToProps 可以不传,如果不传,组件不会监听store的变化,也就是说Store的更新不会引起UI的更新。
    export default connect(
        ({counterReducer}) => ({
            a : counterReducer.a
        })
    )(App);
    

    这个函数的形参中罗列reducer的名字,要用大括号包裹,函数返回值是一个对象,所以必须有一个小括号对。

    这个返回的对象的所有的键,将成为组件的props。

    <h1>根组件{this.props.a}</h1>
    

    mapDispatchToProps

    mapDispatchToProps 用于建立组件跟store.dispatch的映射关系,可以是一个objeft,也可以传入一个函数

    export default connect(
        ({counterReducer}) => ({
            a: counterReducer.a
        }),
        (dispatch) => ({
            add(){
                dispatch({"type" : "ADD"})
            }
        })
    )(App);
    

    logger -- 输出器的安装

    • 一装一引一配 安装依赖
    npm install --save redux-logger
    

    main.js中的配置

    import React from "react";
    import ReactDOM from "react-dom";
    import {createStore , applyMiddleware} from "redux";
    import {Provider} from "react-redux";
    import logger from "redux-logger";
     
    import App from "./App";
    import reducer from "./reducers";
    
    //创建store
    const store = createStore(reducer , applyMiddleware(logger));
     
    ReactDOM.render(
        <Provider store={store}>
            <App></App>
        </Provider>
        ,
        document.getElementById("app")
    );
    

    今后就能在任何一次dispatch发出的时候,看见控制台的自动输出:能够看见改变前的state、发出的action、改变之后的state。


    起源地 » Redux、React和Redux配合、logger | 8月更文挑战

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元