react-redux 调用关系:
react-reduc demo
1.安装插件:npm install --save react-redux
2.创建项目:
demo 效果还是和redux的demo是一样的
demo目录结构:
src下新增了containers文件夹:主要放容器组件;
组件分2类:
- ui组件(components): 不使用redux相关PAI
- 容器组件(containers): 使用redux相关API
app.jsx:
View Code
store.js(固定写法)
1 import {createStore} from 'redux';
2 import {counter} from './reducers';
3
4 const store = createStore(counter);//内部会第一次调用reducer函数得到初始state
5 export default
View Code
counter.jsx:
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:
1 export const INCREMENT='INCREMENT';
2
3
View Code
actions.js
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
View Code
reducers.js:
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
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
View Code
actions.js:添加异步的action:incrementAsync
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的异步方法
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中添加异步方法的传参
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
View Code
其他不变;
我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。