流程和相关api 说明:
- 新建react 项目;
- 安装redux:npm install --save redux
redux相关API说明:
redux中包含: createStore(), applyMiddleware(), combineReducers()
store对象: getState(), dispatch(), subscribe()
react-redux: <Provider>, connect()()
redux核心概念(3个)
action:
默认是对象(同步action), {type: 'xxx', data: value}, 需要通过对应的actionCreator产生,
它的值也可以是函数(异步action), 需要引入redux-thunk才可以
reducer
根据老的state和指定的action, 返回一个新的state
不能修改老的state
store
redux最核心的管理对象
内部管理着: state和reducer
提供方法: getState(), dispatch(action), subscribe(listener)
demo:
项目模板
app.jsx:
1 import React, { Component } from 'react';
2 import {INCREMENT,DECREMENT} from '../redux/action-types'
3 export default class App extends Component {
4
5 increment=()=>{
6 debugger
7 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
8 this.props.store.dispatch({type:INCREMENT,data:number});
9 }
10 decrement=()=>{
11 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
12 let count = this.props.store.getState()-number;
13 if(count>=0){
14 this.props.store.dispatch({type:DECREMENT,data:number});
15 }
16
17 }
18 incrementOdd=()=>{
19 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
20
21 if(number%2 == 1){
22 this.props.store.dispatch({type:INCREMENT,data:number});
23 }
24 }
25 incrementAsync=()=>{
26 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
27 setTimeout(()=>{
28 this.props.store.dispatch({type:INCREMENT,data:number});
29 },1000)
30 }
31 render() {
32 let count= this.props.store.getState();
33 return (
34 <div>
35 <p>click {count} item</p>
36 <div>
37 <select ref={select=>this.select=select}>
38 <option vlaue="1">1</option>
39 <option vlaue="2">2</option>
40 <option vlaue="3">3</option>
41 </select>
42 <button notallow={this.increment}>+</button>
43 <button notallow={this.decrement}>-</button>
44 <button notallow={this.incrementOdd}>increment if odd</button>
45 <button notallow={this.incrementAsync}>increment async</button>
46 </div>
47 </div>
48
49 )
50 }
51
View Code
action-types.js
1 export const INCREMENT='INCREMENT';
2
3
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
index.js
1 import React from "react";
2 import ReactDOM from "react-dom";
3 import App from './component/app';
4 import {createStore} from 'redux'
5 import {counter} from './redux/reducers'
6
7 //生成一个store对象
8 const store = createStore(counter);//内部会第一次调用reducer函数得到初始state
9 function render(){
10 ReactDOM.render(<App store={store}/>,document.getElementById("root"));
11 }
12 //初始化
13 render();
14 //订阅监听,(store 中的状态变化了,就会进行重绘)
15 store.subscribe(function(){
16 render();
17
View Code
demo完善版本:
index.js优化:store重新创建一个store.js index.js引入即可
1 import React from "react";
2 import ReactDOM from "react-dom";
3 import App from './component/app';
4 import store from "./redux/store";
5 //生成一个store对象
6 function render(){
7 ReactDOM.render(<App store={store}/>,document.getElementById("root"));
8 }
9 //初始化
10 render();
11 //订阅监听,(store 中的状态变化了,就会进行重绘)
12 store.subscribe(function(){
13 render();
14
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
添加actions.js 来优化app.js中的更新方法;
action.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
app.js:
1 import React, { Component } from 'react';
2 import {INCREMENT,DECREMENT} from '../redux/action-types'
3 import{increment,decrement} from '../redux/actions'//等同于 import * as actions from '../redux/actions'
4 export default class App extends Component {
5
6 increment=()=>{
7 debugger
8 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
9 this.props.store.dispatch(increment(number));
10 }
11 decrement=()=>{
12 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
13 let count = this.props.store.getState()-number;
14 if(count>=0){
15 this.props.store.dispatch(decrement(number));
16 }
17
18 }
19 incrementOdd=()=>{
20 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
21
22 if(number%2 == 1){
23 this.props.store.dispatch(increment(number));
24 }
25 }
26 incrementAsync=()=>{
27 let number = this.select.value*1;//this.select.value是字符串,*1 变成number
28 setTimeout(()=>{
29 this.props.store.dispatch(increment(number));
30 },1000)
31 }
32 render() {
33 let count= this.props.store.getState();
34 return (
35 <div>
36 <p>click {count} item</p>
37 <div>
38 <select ref={select=>this.select=select}>
39 <option vlaue="1">1</option>
40 <option vlaue="2">2</option>
41 <option vlaue="3">3</option>
42 </select>
43 <button notallow={this.increment}>+</button>
44 <button notallow={this.decrement}>-</button>
45 <button notallow={this.incrementOdd}>increment if odd</button>
46 <button notallow={this.incrementAsync}>increment async</button>
47 </div>
48 </div>
49
50 )
51 }
52
View Code
其他文件不变;