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)

 

posted @ 2021-07-02 16:16  眼里有激光  阅读(110)  评论(0编辑  收藏  举报