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。