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> ) }
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)