简单的实现计算的案例:
1.新建一个react项目
create-react-app react-redux-sample //使用create-react-app脚手架创建一个react项目
cd react-redux-sample //进入react-redux-sample项目根目录
npm start //运行项目
2.引入redux的库
npm install redux@3.7.2 --save
3.编写界面
Counter组件的实现:
import React, { Component } from 'react';
import CounterItem from './CounterItem'
const style = {
width:'200px',
backgroundColor:'skyblue',
margin: '20px'
};
class Counter extends Component {
render() {
return (
<div style={style}>
<CounterItem id={0}></CounterItem>
<CounterItem id={1}></CounterItem>
<div>
合计:<span>20</span>
</div>
</div>
);
}
}
export default Counter;
CounterItem组件的实现:
import React, { Component } from 'react';
const style = {
margin:'10px'
};
class CounterItem extends Component {
constructor(props) {
super(props);
this.addCounter = this.addCounter.bind(this);
this.removeCounter = this.removeCounter.bind(this);
}
addCounter(){
alert('addCounter')
}
removeCounter(){
alert('removeCounter')
}
render() {
return (
<div style={style}>
<button onClick={this.addCounter}> + </button>
<span> 10 </span>
<button onClick={this.removeCounter}> - </button>
</div>
);
}
}
export default CounterItem;
执行的效果:
4.编写store
store.js文件
/*导入createStore函数来创建store对象*/
import { createStore } from 'redux';
/*导入reducer*/
import reducer from './reducer';
/*初始化状态树*/
const initValue=[
{id:0,number:0},
{id:1,number:0}
]
/*store与reducer关联*/
const store=createStore(reducer,initValue);
export default store;
5.编写action
action.js文件
import * as ActionTypes from './actionTypes';
/*每一个action返回的是一个对象,对象必须包含type属性*/
export const addCounter=(id)=>({
type:ActionTypes.addCounter,
id:id,
})
export const removeCounter=(id)=>{
return{
type:ActionTypes.removeCounter,
id:id,
}
}
actiontypes.js文件
export const addCounter = 'addCounter';
export const removeCounter = 'removeCounter';
6.编写reducer
reducer.js文件
import * as ActionTypes from './actionTypes';
/*
参数一:状态树
state:[
{id:0,number:0},
{id:1,number:0}
]
参数二:action 函数
{
type:ActionTypes.removeCounter,
id:id,
}
* */
export default (state,action )=>{
const { id }=action;
console.log(state , action.id , action.type);
switch (action.type){
//点击 +
case ActionTypes.addCounter:
//拷贝一个对象
var s=Object.assign([],state);
s[id].number+=1;
return s;
//点击 -
case ActionTypes.removeCounter:
//拷贝一个对象
var s=Object.assign([],state);
s[id].number-=1;
return s;
default:
return state;
}
}
7.在界面中引入store 对象
在顶级的index.js文件中引入store对象,并且将store对象传递给Counter的子组件
8.计算合计和更新合计
1.Counter组件拿到store对象的数据初始化状态
getOwnState() 函数是给Counter组件的状态机初始化
import React, { Component } from 'react';
import CounterItem from './CounterItem'
const style = {
width:'200px',
backgroundColor:'skyblue',
margin: '20px'
};
class Counter extends Component {
constructor(props){
super(props);
this.state = this.getOwnState();
/**给getOwnState函数绑定this上下文*/
this.getOwnState=this.getOwnState.bind(this);
}
getOwnState() {
/*通过this.props.store对象获取状态树*/
var state=this.props.store.getState();
var sum=0;
/*拿到状态树遍历计算合计*/
state.forEach(function (item,index) {
sum+=item.number;
})
/*返回新的状态机对象*/
return {
sum:sum,
};
}
render() {
/*获取状态机中的合计*/
const sum =this.state.sum;
return (
<div style={style}>
{/*又将唯一的store传给子组件*/}
<CounterItem id={0} store={this.props.store}></CounterItem>
<CounterItem id={1} store={this.props.store}></CounterItem>
<div>
合计:<span>{sum}</span>
</div>
</div>
);
}
}
export default Counter;
2.Counter组件监听store中状态树的更新
//...
class Counter extends Component {
constructor(props){
//...
this.onChange=this.onChange.bind(this);
}
getOwnState() {
//...
}
render() {
//...
}
/*如果store 发生了变化,将回调这个函数*/
onChange() {
//如果store 发生了变化,重新获取store中的值
this.setState(this.getOwnState());
}
componentDidMount() {
// 监听store 的变化
this.props.store.subscribe(this.onChange);
}
componentWillUnmount() {
//取消监听store 的变化
this.props.store.unsubscribe(this.onChange);
}
}
export default Counter;
9.CounterItem组件实现加和减
1.CounterItem组件拿到store对象的数据初始化状态
import React, { Component } from 'react';
import * as Actions from '../action';
const style = {
margin:'10px'
};
class CounterItem extends Component {
constructor(props) {
super(props);
this.state=this.getOwnState();
this.addCounter = this.addCounter.bind(this);
this.removeCounter = this.removeCounter.bind(this);
this.getOwnState = this.getOwnState.bind(this);
}
/**初始化状态机*/
getOwnState(){
/**获取父亲组件传递过来的store对象*/
var {id,store}=this.props;
/**获取状态树中对应的数据*/
var oldNumber=store.getState()[id].number;
/**返回一个对象给状态机*/
return {
number:oldNumber,
}
}
addCounter(){
}
removeCounter(){
}
render() {
var num=this.state.number;
return (
<div style={style}>
<button onClick={this.addCounter}> + </button>
<span>{num}</span>
<button onClick={this.removeCounter}> - </button>
</div>
);
}
}
export default CounterItem;
2.点击加和减发送action
//...
class CounterItem extends Component {
constructor(props) {
//....
}
getOwnState(){
//...
}
addCounter(){
var{id,store}=this.props;
//调用 store对象的dispatch来分发 + action
store.dispatch( Actions.addCounter(id) );
}
removeCounter(){
var{id,store}=this.props;
//调用 store对象的dispatch来分发 - action
store.dispatch( Actions.removeCounter(id) );
}
render() {
//...
}
}
export default CounterItem;
3.监听store中状态树的更新
//...
class CounterItem extends Component {
constructor(props) {
super(props);
//...
this.onChange = this.onChange.bind(this);
}
//...
render() {
//...
}
onChange() {
//如果store 发生了变化,重新获取store中的值
this.setState(this.getOwnState());
}
componentDidMount() {
// 监听store 的变化
this.props.store.subscribe(this.onChange);
}
componentWillUnmount() {
//取消监听store 的变化
this.props.store.unsubscribe(this.onChange);
}
}
export default CounterItem;
最后执行的效果: