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,自己做了一层封装。