1.先创建count和person两个组件
2.创建count的store相关的文件夹。
store/modules/count
1.constant.js
2.createActions.js
3.index.js
4.reducer.js
index.js
import { legacy_createStore as createStore } from "redux";
import countReducer from "./reducer.js";
const countStore = createStore(countReducer);
export default countStore;
先写index.js 创建store,因为以后count组件的操作都是store.dospatch({type:xxx,data:xxx}),然后获取store是通过store.getState()
然后创建reducer.js
import { INCREMENT, DECREMENT } from "./constant";
const initialState = 0;
function countReducer(preState = initialState, action) {
const { type, data } = action;
console.log("count reducer", type, data);
switch (type) {
case INCREMENT:
return preState + data;
case DECREMENT:
return preState - data;
default:
return preState;
}
}
export default countReducer;
创建createActions.js
import { INCREMENT, DECREMENT, ASYNC_INCREMENT } from "./constant";
export function incrementAction(data) {
return { type: INCREMENT, data };
}
export function decrementAction(data) {
return { type: DECREMENT, data };
}
export function asyncIncrementAction(data) {
setTimeout(() => {
return { type: ASYNC_INCREMENT, data };
}, 1000);
}
constant.js
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
export const ASYNC_INCREMENT = "asyncIncrement";
这个时候在count组件中通过store.getState()就可以获得值了,但是注意,页面是不会刷新的,所以我们要使用另外一个方法store.subscribe这个方法,当rudux里面的值发生改变,就会调用这个方法,执行里面的回调函数。
import React, { Component } from "react";
import store from "../store/modules/count";
import {
incrementAction,
decrementAction,
asyncIncrementAction,
} from "../store/modules/count/createActions";
export default class Count extends Component {
state = { count: store.getState() };
componentDidMount() {
store.subscribe(() => {
const count = store.getState();
this.setState({ count });
});
}
increment = () => {
console.log(store.getState());
store.dispatch(incrementAction(1));
};
decrement = () => {
store.dispatch(decrementAction(1));
};
asyncIncrement = () => {
store.dispatch(asyncIncrementAction(1));
};
render() {
return (
<div>
<div>当前Count:{store.getState()}</div>
<button onClick={this.increment}>点我加1</button>
<button onClick={this.decrement}>点我减1</button>
<button onClick={this.asyncIncrement}>点我异步加1</button>
<hr />
</div>
);
}
}
1.总结
使用redux的时候,
记住两点,redux里面是数据
组件中要使用store.dispacth(atction)来变更redux中的数据
组件通过store.getState()来获取里面的数据。
实现的化,只考虑store.js和reducer.js
store.js的创建就是公式。
import { legacy_createStore as createStore } from "redux";
import countReducer from "./reducer.js";
const countStore = createStore(countReducer);
export default countStore;
reducer.js就是一个纯函数,function countReducer(preState = initialState, action)
这个样子,基本reudx的使用就没问题了。
接下来还有异步的处理。
组件的store的dispatch里面只能是一个action,你dispatch里面是一个函数的化,是会报错的,这个时候,你需要让store执行这个函数,就需要用中间件。
下载redux-thunk
import { legacy_createStore as createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import countReducer from "./reducer.js";
const countStore = createStore(countReducer, applyMiddleware(thunk));
export default countStore;
给store.js使用中间件,这样子sotre.dispatch(fn)就没问题了,fn是一个异步函数。store收到这个函数,就会马上执行。并且会传入dispatch这个参数。
最终还是会dispatch一个action。store遇到这个action,就会调用reducer这个函数,传入当前的state和这个action。
export function asyncIncrementAction(data) {
return (dispatch) => {
setTimeout(() => {
dispatch(incrementAction(data));
}, 1000);
};
}
总结2
一个组件对应一个store.js,一个store.js对应于一个reducer.js
如果有多个组件的化,我们就要创建很多的store和reducer。
这个时候可以使用react-redux。
react-redux是react团队facebook参照redux,自己做了一层封装。