一、基本使用
二、優化
三、數據共享
四、react-redux開發者工具的使用
五、代碼
1 import React, { Component } from 'react' 2 import Count from './containers/Count' //引入的Count的容器組件 3 import Person from './containers/Person' //引入的Person的容器組件 4 5 export default class App extends Component { 6 render() { 7 return ( 8 <div> 9 <Count/> 10 <hr/> 11 <Person/> 12 </div> 13 ) 14 } 15 }
2. index.js
1 import React from 'react' 2 import ReactDOM from 'react-dom' 3 import App from './App' 4 import store from './redux/store' 5 import {Provider} from 'react-redux' 6 7 ReactDOM.render( 8 /* 此處需要用Provider包裹App,目的是讓App所有的後代容器組件都能接收到store */ 9 <Provider store={store}> 10 <App/> 11 </Provider>, 12 document.getElementById('root') 13 )
3.redux/store.js
1 /* 2 該文件專門用於暴露一個store對象,整個應用只有一個store對象 3 */ 4 5 //引入createStore,專門用於創建redux中最爲核心的store對象 6 import {createStore,applyMiddleware} from 'redux' 7 //引入彙總之後的reducer 8 import reducer from './reducers' 9 //引入redux-thunk,用於支持異步action 10 import thunk from 'redux-thunk' 11 //引入redux-devtools-extension 12 import {composeWithDevTools} from 'redux-devtools-extension' 13 14 //暴露store 15 export default createStore(reducer,composeWithDevTools(applyMiddleware(thunk)))
4.constant.js
1 /* 2 該模塊是用於定義action對象中type類型的常量值,目的只有一個:便於管理的同時防止程序員單詞寫錯 3 */ 4 export const INCREMENT = 'increment' 5 export const DECREMENT = 'decrement' 6 export const ADD_PERSON = 'add_person'
5.redux/reducers/index.js
1 /* 2 該文件用於彙總所有的reducer爲一個總的reducer 3 */ 4 //引入combineReducers,用於彙總多個reducer 5 import {combineReducers} from 'redux' 6 //引入爲Count組件服務的reducer 7 import count from './count' 8 //引入爲Person組件服務的reducer 9 import persons from './person' 10 11 //彙總所有的reducer變爲一個總的reducer 12 export default combineReducers({ 13 count, 14 persons 15 })
6.redux/reducers/count.js
1 /* 2 1.該文件是用於創建一個爲Count組件服務的reducer,reducer的本質就是一個函數 3 2.reducer函數會接到兩個參數,分別爲:之前的狀態(preState),動作對象(action) 4 */ 5 import {INCREMENT,DECREMENT} from '../constant' 6 7 const initState = 0 //初始化狀態 8 export default function countReducer(preState=initState,action){ 9 // console.log('countReducer@#@#@#'); 10 //從action對象中獲取:type、data 11 const {type,data} = action 12 //根據type決定如何加工數據 13 switch (type) { 14 case INCREMENT: //如果是加 15 return preState + data 16 case DECREMENT: //若果是減 17 return preState - data 18 default: 19 return preState 20 } 21 }
7.redux/reducers/person.js
1 import {ADD_PERSON} from '../constant' 2 3 //初始化人的列表 4 const initState = [{id:'001',name:'tom',age:18}] 5 6 export default function personReducer(preState=initState,action){ 7 // console.log('personReducer@#@#@#'); 8 const {type,data} = action 9 switch (type) { 10 case ADD_PERSON: //若是添加一個人 11 //preState.unshift(data) //此處不可以這樣寫,這樣會導致preState被改寫了,personReducer就不是純函數了。 12 return [data,...preState] 13 default: 14 return preState 15 } 16 }
8.redux/actions/count.js
1 /* 2 該文件專門爲Count組件生成action對象 3 */ 4 import {INCREMENT,DECREMENT} from '../constant' 5 6 //同步action,就是指action的值爲Object類型的一般對象 7 export const increment = data => ({type:INCREMENT,data}) 8 export const decrement = data => ({type:DECREMENT,data}) 9 10 //異步action,就是指action的值爲函數,異步action中一般都會調用同步action,異步action不是必須要用的。 11 export const incrementAsync = (data,time) => { 12 return (dispatch)=>{ 13 setTimeout(()=>{ 14 dispatch(increment(data)) 15 },time) 16 } 17 }
9.redux/actions/person.js
1 import {ADD_PERSON} from '../constant' 2 3 //創建增加一個人的action動作對象 4 export const addPerson = personObj => ({type:ADD_PERSON,data:personObj})
10.containers/count.jsx
1 import React, { Component } from 'react' 2 //引入action 3 import { 4 increment, 5 decrement, 6 incrementAsync 7 } from '../../redux/actions/count' 8 //引入connect用於連接UI組件與redux 9 import {connect} from 'react-redux' 10 11 //定義UI組件 12 class Count extends Component { 13 14 state = {carName:'奔馳c63'} 15 16 //加法 17 increment = ()=>{ 18 const {value} = this.selectNumber 19 this.props.increment(value*1) 20 } 21 //減法 22 decrement = ()=>{ 23 const {value} = this.selectNumber 24 this.props.decrement(value*1) 25 } 26 //奇數再加 27 incrementIfOdd = ()=>{ 28 const {value} = this.selectNumber 29 if(this.props.count % 2 !== 0){ 30 this.props.increment(value*1) 31 } 32 } 33 //異步加 34 incrementAsync = ()=>{ 35 const {value} = this.selectNumber 36 this.props.incrementAsync(value*1,500) 37 } 38 39 render() { 40 //console.log('UI組件接收到的props是',this.props); 41 return ( 42 <div> 43 <h2>我是Count組件,下方組件總人數爲:{this.props.renshu}</h2> 44 <h4>當前求和爲:{this.props.count}</h4> 45 <select ref={c => this.selectNumber = c}> 46 <option value="1">1</option> 47 <option value="2">2</option> 48 <option value="3">3</option> 49 </select> 50 <button onClick={this.increment}>+</button> 51 <button onClick={this.decrement}>-</button> 52 <button onClick={this.incrementIfOdd}>當前求和爲奇數再加</button> 53 <button onClick={this.incrementAsync}>異步加</button> 54 </div> 55 ) 56 } 57 } 58 59 //使用connect()()創建並暴露一個Count的容器組件 60 export default connect( 61 state => ({ 62 count:state.count, 63 personCount:state.persons.length 64 }), 65 {increment,decrement,incrementAsync} 66 )(Count)
11.containers/persion.jsx
1 import React, { Component } from 'react' 2 import {nanoid} from 'nanoid' 3 import {connect} from 'react-redux' 4 import {addPerson} from '../../redux/actions/person' 5 6 class Person extends Component { 7 8 addPerson = ()=>{ 9 const name = this.nameNode.value 10 const age = this.ageNode.value*1 11 const personObj = {id:nanoid(),name,age} 12 this.props.addPerson(personObj) 13 this.nameNode.value = '' 14 this.ageNode.value = '' 15 } 16 17 render() { 18 return ( 19 <div> 20 <h2>我是Person組件,上方組件求和爲{this.props.count}</h2> 21 <input ref={c=>this.nameNode = c} type="text" placeholder="輸入名字"/> 22 <input ref={c=>this.ageNode = c} type="text" placeholder="輸入年齡"/> 23 <button onClick={this.addPerson}>添加</button> 24 <ul> 25 { 26 this.props.persons.map((p)=>{ 27 return <li key={p.id}>{p.name}--{p.age}</li> 28 }) 29 } 30 </ul> 31 </div> 32 ) 33 } 34 } 35 36 export default connect( 37 state => ({ 38 persons:state.persons, 39 count:state.count 40 }),//映射狀態 41 {addPerson}//映射操作狀態的方法 42 )(Person)