redux
2024-04-10 01:50:09  阅读数 304

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