zoukankan      html  css  js  c++  java
  • react 学习(2)在react中使用react-redux

    前言

      如果你对redux还不太熟悉,那么建议你先看完我的这篇文章再继续阅读

    准备工作

      1.使用react-router-dom搭建路由

      2.使用redux搭建是store

      例子

        router

    import {HashRouter, Switch} from "react-router-dom";
    import { createRouter,routerType } from './createRoute';
    import store from './../store/index';
    import {Provider} from "react-redux";
    const routers:routerType[]=[
      {
        cPath:"login/login",
        path:"/login"
      },
      {
        cPath:"home/index",
        path:"/"
      }
    ];
    
    export function Router(){
      return (
      <Provider store={store}>
        <HashRouter>
        <Switch>
          {createRouter(routers)}
        </Switch>
      </HashRouter>
      </Provider>
      )
    }
    View Code

        store

    import { createStore, applyMiddleware,compose } from "redux";
    //定义state,定义初始数据结构
    const stateDefault = {
      default1: "初始化数据",
    };
    const reducer = (state:any,action:any) => {
      return {...state};
    };
    
    
    let store=createStore(reducer,stateDefault);
    
    export default store;

    react-redux中api

      Provider:react-redux提供的一个组件,只有被它包裹的组件才能够使用connect函数

    //
      //一般都是在路由中将<Provider>包裹路由根节点<HashRouter>,这样所有在<HashRouter>中的路由组件都能使用connect方法,
      //只要是处在<Provider>包裹中的组件,不管是直接包裹还是间接包裹,都能够使用connect,vue中的privide也是借鉴于此
    export function Router(){
      return (
        //Provider 接受一个redux-createStore生成的store对象
      <Provider store={store}> 
        <HashRouter>
        <Switch>
          {createRouter(routers)}
        </Switch>
      </HashRouter>
      </Provider>
      )
    }

      connect:react-redux提供的用来连接组件和redux的函数

    import React  from 'react';
    import { connect } from 'react-redux';
    
    //这里拿router中的login组件做案例
    class Login extends React.Component{
        componentDidMount(){
            //如果不使用connect连接组件,并且你没有手动给Login组件传递props的话,那么这里的props会得到一个空{}对象
            console.log('没有使用connect连接',this.props); //{}
            //使用connect连接Login与redux之后,Login的props中,会注入一些store中的属性
            console.log('使用connect连接',this.props); //{dispatch,...}
        }
        render(){
            return (<div>测试登录页</div>)
        }
    }
    //不使用connect连接redux,直接抛出Login组件即可
    export default Login;
    
    //使用connect之后,connect方法会返回一个新的连接redux的组件,我们将新的组件抛出即可。这里connect不会对原有的Login进行任何更改,你仍然可以在其他的地方调用Login组件
    export default connect()(Login) //调用connect方法后会返回一个方法

        connect参数:connect可以接受一些参数,以便你能更好的使用store中的属性和方法,connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

          mapStateToProps:

    import React  from 'react';
    import { connect } from 'react-redux';
    
    class Login extends React.Component{
        componentDidMount(){
            console.log(this.props); //可以看到mapStateToProps中注入到props的state中的属性
        }
        render(){
            return (<div>测试登录页</div>)
        }
    }
    
    export default connect(mapStateToProps)(Login)
    
    
    // 接受两个参数state,state为store中的state,ownProps为Login组件接收到的props,返回一个对象{}
    function mapStateToProps(state:any,ownProps:any) {
    
        //在mapStateToProps中return的值,会被注入到Login组件的props中
        return {prop1:"test prop1"} 
    
        //你可以通过将state return,把state中的属性注入到Login中
        return {...state}
    }

          mapDispatchToProps:

    import React  from 'react';
    import { connect } from 'react-redux';
    
    class Login extends React.Component{
        componentDidMount(){
            let a:any= this.props;
            a.dis1();//在这里调用注入的dis1方法,分发预先定义的action
        }
        render(){
            return (<div>测试登录页</div>)
        }
    }
    
    export default connect(undefined,mapDispatchToProps)(Login)
    
    //将自定义函数注入到Login的props中
    //因为mapDispatchToProps接受一个参数,参数dispatch等效于store.diapatch方法,所以我们可以在自定义函数中触发action
    function mapDispatchToProps(dispatch:any){
        //在这里return的对象,会结构注入到Login的props中
        return {
            //定义一个key为dis1的属性,它是一个方法
            dis1(){
                dispatch({type:"dis1"}) //使用参数dispatch 分发一个store中的action
            }
        }
    }

          mapDispatchToProps:

    import React  from 'react';
    import { connect } from 'react-redux';
    
    class Login extends React.Component{
        componentDidMount(){
            let props:any= this.props;
            console.log("login props",props)
        }
        render(){
            return (<div>测试登录页</div>)
        }
    }
    
    export default connect(mapStateToProps,mapDispatchToProps,mergeProps)(Login)
    
    //映射state到props
    function mapStateToProps(state:any){
        return {
            mapProp1:"mapProp1"
        }
    }
    
    //映射dispatch到props
    function mapDispatchToProps(dispatch:any){
        return {
            dis1(){
                dispatch({type:"dis1"})
            }
        }
    }
    
    //组合mapDispatchToProps和mapStateToProps即将注入到Login组件的props中的内容,
    //即便在mapDispatchToProps和mapStateToProps的return中定义了属性,只要添加了mergeProps参数,那么注入到Login的props中的内容,只由mergeProps的reurn值决定
    function mergeProps(stateProps:any, dispatchProps:any, ownProps:any){
        console.log(stateProps,dispatchProps,ownProps)
        return {
           ...stateProps,
           ...dispatchProps
        }
    }

          options:

    import React  from 'react';
    import { connect } from 'react-redux';
    
    class Login extends React.Component{
        componentDidMount(){
            let props:any= this.props;
            console.log("login props",props)
        }
        render(){
            return (<div>测试登录页</div>)
        }
    }
    const options={
        pure:true,// 如果为 true,connector 将执行 shouldComponentUpdate 并且浅对比 mergeProps 的结果,避免不必要的更新,前提是当前组件是一个“纯”组件,它不依赖于任何的输入或 state 而只依赖于 props 和 Redux store 的 state。默认值为 true。
        withRef:false,// 如果为 true,connector 会保存一个对被包装组件实例的引用,该引用通过 getWrappedInstance() 方法获得。默认值为 false
    }
    export default connect(undefined,undefined,undefined,options)(Login)
  • 相关阅读:
    appium连接真机时,报错:error: device unauthorized.
    python使用163邮箱发送测试报告遇到smtplib.SMTPAuthenticationError: (550, b'User has no permission')问题
    logging日志重复打印问题
    python实现text/html的get请求
    python实现Post请求四种请求体
    selenium异常类
    unittest所有断言方法
    windows下Jenkins+webdriver无法启动浏览器
    python3+selenium3之 解决:'chromedriver' executable needs to be in PATH问题
    python学习(6)--logging打印日志
  • 原文地址:https://www.cnblogs.com/wrhbk/p/14963782.html
Copyright © 2011-2022 走看看