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

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章