当前位置: 代码迷 >> 综合 >> redux(三)react-redux容器组件链接UI组件映射store中的state到props
  详细解决方案

redux(三)react-redux容器组件链接UI组件映射store中的state到props

热度:1   发布时间:2023-12-14 10:05:49.0

cnpm i react-redux,然后在App.js中引入react-redux的Provider组件(react-redux的容器组件,始终在最外层),引入当前目录下store下的store.js,将store传递给Provider组件:

App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Todos from "./components/Todos"
import Number2 from './Number2'import {Provider} from 'react-redux';
import store from './store/store';
class App extends Component {render() {return (<Provider store={store}><div className="App"><Todos /><hr/><Number2/></div></Provider>);}
}export default App;

在Number2组件中引入react-redux的connect函数,不再需要之前的actions.js文件了,但是需要actionCreator.js:

import React, { Component } from 'react';
// import actions from "../store/number/actions";不需要了
// import store from "../store/store";不需要了
import actionCreator from "../store/number/actionCreator"; //需要actionCreator中的action
import {connect} from 'react-redux';
class Number2 extends Component {constructor(){super();this.state = {val: "0"}}render() {console.log(this.props)return (<div><button>++</button><input type="text" /><button >--</button></div>);}
}let Connected = connect(state=>state)(Number2);//此时就能获取store中的state了,14行测试打印结果export default Connected;

14行输出之前定义的state:


connect函数可以接受两个参数,两个都是回调函数,第一个回调函数中接收store中的state,意思是将store中的state映射到Number2组件的props中,第二个回调函数中接收store的dispatch,返回一个对象,对象包含所需的action的dispatch函数:

import React, { Component } from 'react';
// import actions from "../store/number/actions";不需要了
// import store from "../store/store";不需要了
import actionCreator from "../store/number/actionCreator"; //需要actionCreator中的action
import {connect} from 'react-redux';
class Number2 extends Component {constructor(){super();this.state = {val: "0"}}render() {console.log(this.props)return (<div><button>++</button><input type="text" /><button >--</button></div>);}
}let mapDispatchToProps = (dispatch)=>{return {add(){dispatch(actionCreator.intNumber());},sub(){dispatch(actionCreator.decNumber());},input(val){dispatch(actionCreator.inputNumber(val));}}
}let Connected = connect(state=>state, mapDispatchToProps)(Number2);//链接容器组件到UI组件,此时就能获取store中的state了,14行测试打印结果
/*connect函数可以接受两个参数,两个都是回调函数,第一个回调函数中接收store中的state,return state或一个对象,
意思是将store中的state映射到Number2组件的props中,第二个回调函数中接收store的dispatch,
返回一个对象,对象包含所需的action的dispatch函数*/export default Connected;

此时Number2组件中就直接在props中获取并发送对应的action了:


import React, { Component } from 'react';
// import actions from "../store/number/actions";不需要了
// import store from "../store/store";不需要了
import actionCreator from "../store/number/actionCreator"; //需要actionCreator中的action
import {connect} from 'react-redux';
class Number2 extends Component {// constructor(){//   super();//   this.state = {//   	val: "0"//   }// }render() {console.log(this.props)let {add, sub, input, number} = this.props;return (<div><button onClick={add}>++</button><input type="text" value={number.number} onChange={(e)=>input(e.target.value)}/><button onClick={sub}>--</button></div>);}
}let mapDispatchToProps = (dispatch)=>{return {add(){dispatch(actionCreator.intNumber());},sub(){dispatch(actionCreator.decNumber());},input(val){dispatch(actionCreator.inputNumber(val));}}
}let Connected = connect(state=>state, mapDispatchToProps)(Number2);//链接容器组件到UI组件,此时就能获取store中的state了,14行测试打印结果
/*connect函数可以接受两个参数,两个都是回调函数,第一个回调函数中接收store中的state,return state或一个对象,
意思是将store中的state映射到Number2组件的props中,第二个回调函数中接收store的dispatch,
返回一个对象,对象包含所需的action的dispatch函数*/export default Connected;

测试没毛病!

不过这种方式需要一条一条手动写出每个action才能映射到props,还有一种方式,引入redux的bindActionCreators,再将上面代码改为如下:

import React, { Component } from 'react';
// import actions from "../store/number/actions";不需要了
// import store from "../store/store";不需要了
import actionCreator from "../store/number/actionCreator"; //需要actionCreator中的action
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';class Number2 extends Component {render() {console.log(this.props)// let {add, sub, input, number} = this.props;// return (//   <div>//     <button onClick={add}>++</button>//     <input type="text" value={number.number} onChange={(e)=>input(e.target.value)}/>//     <button onClick={sub}>--</button>//   </div>// );let {methods, number} = this.props;return (<div><button onClick={methods.intNumber}>++</button><input type="text" value={number.number} onChange={(e)=>methods.inputNumber(e.target.value)}/><button onClick={methods.decNumber}>--</button></div>);}
}let mapDispatchToProps = (dispatch)=>{return {// add(){// 	dispatch(actionCreator.intNumber());// },// sub(){// 	dispatch(actionCreator.decNumber());// },// input(val){// 	dispatch(actionCreator.inputNumber(val));// }/*传入actionCreator和dispatch,此时无论有多少action全都映射到props.methods中,相当于语法糖*/methods: bindActionCreators(actionCreator, dispatch)}
}let Connected = connect(state=>state, mapDispatchToProps)(Number2);//链接容器组件到UI组件,此时就能获取store中的state了,14行测试打印结果
/*connect函数可以接受两个参数,两个都是回调函数,第一个回调函数中接收store中的state,return state或一个对象,
意思是将store中的state映射到Number2组件的props中,第二个回调函数中接收store的dispatch,
返回一个对象,对象包含所需的action的dispatch函数*/export default Connected;

同样connect函数的第一个函数参数也可以提取出来,提取出来有一个好处,可以定义一个类似计算属性的属性:

let mapDispatchToProps = dispatch=>{return {// add(){// 	dispatch(actionCreator.intNumber());// },// sub(){// 	dispatch(actionCreator.decNumber());// },// input(val){// 	dispatch(actionCreator.inputNumber(val));// }/*传入actionCreator和dispatch,此时无论有多少action全都映射到props.methods中,相当于语法糖*/methods: bindActionCreators(actionCreator, dispatch)}
}let mapStateToProps = state=>{return {number: state.number,numberSquare: Math.pow(state.number.number, 2)//将第一个函数提出来写的好处就在这}
}// let Connected = connect(state=>state, mapDispatchToProps)(Number2);//链接容器组件到ui,此时就能获取store中的state了,14行测试打印结果
/*connect函数可以接受两个参数,两个都是回调函数,第一个回调函数中接收store中的state,return state或一个对象,
意思是将store中的state映射到Number2组件的props中,第二个回调函数中接收store的dispatch,
返回一个对象,对象包含所需的action的dispatch函数*/
let Connected = connect(mapStateToProps, mapDispatchToProps)(Number2)export default Connected;

点击++:


小结:其实主要就是利用react-redux的connect链接容器组件和UI组件,同时用了redux的bindActionCreators语法糖,从而省略掉了之前的actions.js文件,不再需要此文件了,因为react-redux封装了actions。

  相关解决方案