react-redux 调用关系:
react-reduc demo
1.安装插件:npm install --save react-redux
2.创建项目:
项目模板:https://www.cnblogs.com/lixiuming521125/p/16698004.html
demo 效果还是和redux的demo是一样的
demo目录结构:
src下新增了containers文件夹:主要放容器组件;
组件分2类:
- ui组件(components): 不使用redux相关PAI
- 容器组件(containers): 使用redux相关API
app.jsx:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import React from 'react'; 2 import {connect} from 'react-redux' 3 4 import Counter from '../component/counter'; 5 import{increment,decrement} from '../redux/actions'//等同于 import * as actions from '../redux/actions' 6 7 //connect 第一个括号把参数(即组件需要的参数 自动解构好)传入到第二个括号中的组件 8 export default connect( 9 state=>({number:state}),//第一个state是参数,相当于执行了 这个函数 function xx (state){return {number:state}} 10 {increment,decrement}//相当于:{increment:increment,decrement:decrement} 属性值increment action名字increment 11 )(Counter)View Code
store.js(固定写法)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import {createStore} from 'redux'; 2 import {counter} from './reducers'; 3 4 const store = createStore(counter);//内部会第一次调用reducer函数得到初始state 5 export default store;View Code
counter.jsx:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import React, { Component } from 'react'; 2 import PropTypes from 'prop-types'; 3 export default class Counter extends Component { 4 5 static propTypes={ 6 number:PropTypes.number.isRequired, 7 increment:PropTypes.func.isRequired, 8 decrement:PropTypes.func.isRequired, 9 } 10 11 increment=()=>{ 12 debugger 13 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 14 this.props.increment(number); 15 } 16 decrement=()=>{ 17 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 18 let count = this.props.number-number; 19 if(count>=0){ 20 this.props.decrement(number); 21 } 22 23 } 24 incrementOdd=()=>{ 25 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 26 27 if(number%2 == 1){ 28 this.props.increment(number); 29 } 30 } 31 incrementAsync=()=>{ 32 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 33 setTimeout(()=>{ 34 this.props.increment(number); 35 },1000) 36 } 37 render() { 38 let count= this.props.number; 39 return ( 40 <div> 41 <p>click {count} item</p> 42 <div> 43 <select ref={select=>this.select=select}> 44 <option vlaue="1">1</option> 45 <option vlaue="2">2</option> 46 <option vlaue="3">3</option> 47 </select> 48 <button onClick={this.increment}>+</button> 49 <button onClick={this.decrement}>-</button> 50 <button onClick={this.incrementOdd}>increment if odd</button> 51 <button onClick={this.incrementAsync}>increment async</button> 52 </div> 53 </div> 54 55 ) 56 } 57 }View Code
其他:
action-types.js:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 export const INCREMENT='INCREMENT'; 2 3 export const DECREMENT='DECREMENT';View Code
actions.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 包含所有action creator 3 */ 4 import{INCREMENT,DECREMENT} from './action-types' 5 6 /** */ 7 export const increment=(number)=>({type:INCREMENT,data:number}); 8 9 export const decrement=(number)=>({type:DECREMENT,data:number});View Code
reducers.js:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 这是一个包含n个reducer函数的模块 3 */ 4 import{INCREMENT,DECREMENT} from './action-types' 5 6 export function counter(state=0,action){ 7 console.log(state); 8 console.log(action); 9 switch(action.type){ 10 case INCREMENT: 11 return state+action.data; 12 case DECREMENT: 13 return state-action.data; 14 default: 15 return state 16 } 17 }View Code
redux的异步请求:
问题点:
1.redux默认是不能进行异步处理的(前面的demo可以,是因为在react中进行操作的)
count.jsx中的代码片段:
1 incrementAsync=()=>{ 2 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 3 setTimeout(()=>{ 4 this.props.increment(number); 5 },1000) 6 }
需要是更改为如下,即 直接使用redux的异步方法;
1 incrementAsync=()=>{ 2 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 3 this.props.incrementAsync(number); 4 }
2.应用中又需要在redux中执行异步任务(ajax、定时器)
解决办法:
使用中间件 redux-thunk;
安装:npm install --save redux-thunk
demo修改:
store.js :引入redux-thunk
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import {createStore,applyMiddleware} from 'redux'; 2 import {counter} from './reducers'; 3 import thunk from 'redux-thunk'; 4 5 //内部会第一次调用reducer函数得到初始state 6 const store = createStore(counter, 7 applyMiddleware(thunk)//应用上异步中间件 8 ); 9 export default store;View Code
actions.js:添加异步的action:incrementAsync
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 包含所有action creator 3 */ 4 import{INCREMENT,DECREMENT} from './action-types' 5 6 /** 7 * 同步action 返回一个对象 8 */ 9 export const increment=(number)=>({type:INCREMENT,data:number}); 10 11 export const decrement=(number)=>({type:DECREMENT,data:number}); 12 13 /** 14 * 异步action 返回一个函数 15 * @param {*} number 16 * @returns 17 */ 18 export const incrementAsync=(number)=>{ 19 return dispatch=>{ 20 setTimeout(()=>{ 21 dispatch(increment(number)); 22 },1000) 23 } 24 };View Code
counter.jsx:修改异步方法;直接执行redux的异步方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import React, { Component } from 'react'; 2 import PropTypes from 'prop-types'; 3 export default class Counter extends Component { 4 5 static propTypes={ 6 number:PropTypes.number.isRequired, 7 increment:PropTypes.func.isRequired, 8 decrement:PropTypes.func.isRequired, 9 incrementAsync:PropTypes.func.isRequired 10 } 11 12 increment=()=>{ 13 debugger 14 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 15 this.props.increment(number); 16 } 17 decrement=()=>{ 18 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 19 let count = this.props.number-number; 20 if(count>=0){ 21 this.props.decrement(number); 22 } 23 24 } 25 incrementOdd=()=>{ 26 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 27 28 if(number%2 == 1){ 29 this.props.increment(number); 30 } 31 } 32 incrementAsync=()=>{ 33 let number = this.select.value*1;//this.select.value是字符串,*1 变成number 34 this.props.incrementAsync(number); 35 } 36 render() { 37 let count= this.props.number; 38 return ( 39 <div> 40 <p>click {count} item</p> 41 <div> 42 <select ref={select=>this.select=select}> 43 <option vlaue="1">1</option> 44 <option vlaue="2">2</option> 45 <option vlaue="3">3</option> 46 </select> 47 <button onClick={this.increment}>+</button> 48 <button onClick={this.decrement}>-</button> 49 <button onClick={this.incrementOdd}>increment if odd</button> 50 <button onClick={this.incrementAsync}>increment async</button> 51 </div> 52 </div> 53 54 ) 55 } 56 }View Code
app.jsx:添加了异步方法后需要在connect中添加异步方法的传参
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import React from 'react'; 2 import {connect} from 'react-redux' 3 4 import Counter from '../component/counter'; 5 import{increment,decrement,incrementAsync} from '../redux/actions'//等同于 import * as actions from '../redux/actions' 6 7 //connect 第一个括号把参数(即组件需要的参数 自动解构好)传入到第二个括号中的组件 8 export default connect( 9 state=>({number:state}),//第一个state是参数,相当于执行了 这个函数 function xx (state){return {number:state}} 10 {increment,decrement,incrementAsync}//相当于:{increment:increment,decrement:decrement} 属性值increment action名字increment 11 )(Counter)View Code
其他不变;
标签:demo,number,value,react,increment,import,redux,select From: https://www.cnblogs.com/lixiuming521125/p/16701163.html