React笔记 (九)Redux的工作原理,使用总结及最佳写法

478 阅读3分钟

React-Redux是Redux的官方React绑定库。它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据

安装

在你的React app中使用React-Redux:

npm install --save redux

原理

Redux的原理其实就是把数据放在一个仓库中(类似于Vuex),组件可以在任何地方储存和提取仓库中的内容,具体关系看下图:

首先是Store,它是数据存取的中间点,想要存或者取数据必须经过他,可以把他想象成一个图书馆前台,而Reducers就像是一个找书的店员。假如组件想改变Store里的内容,首先组件需要发出一个请求也就是图中的Action,之后交给Store,Store会带着这个请求递给Reducers就是找书的店员,它会分析请求的内容,具体要干什么事,操作好以后Reducers会返回一个新的数据给Store,Store接到数据就会返回给发起请求的组件,从而完成一次通信。

写法

首先在根目录新建一个名为store的文件夹,文件夹里分别有Store本身index.js和reducers.js两个文件:

store.js

之后在index中引入redux并调用reducers方法并暴露出去:

import { createStore } from 'redux'
import reducer from './reducer.js'

const store = createStore(reducer);

export default store;

reducers.js

在reducers文件夹里需要声明一个仓库数据的默认值,之后直接暴露一个函数出去,这个函数接受两个参数,一个是仓库之前的值,另一个就是组件递过来的请求,reducers就根据递过来的请求来操作仓库里的数据,最后把操作后的数据return出去:

const defaultState = {
  inputValue: "123",
  list: [1,2]
}

export default (state = defaultState, action) => {
  if (action.type === "change_input_value") {
    const newState = JSON.parse(JSON.stringify(state));
    newState.inputValue = action.inputValue;
    return newState;
  }
  if (action.type === "add_list_item") {
    const newState = JSON.parse(JSON.stringify(state));
    newState.list.push(action.inputValue);
    newState.inputValue = "";
    return newState;
  }
  if (action.type === "clear_list_item") {
    const newState = JSON.parse(JSON.stringify(state));
    newState.list.splice(action.itemIndex, 1);
    return newState;
  }
  return state
}

组件里

在组件里首先需要引入store.js ,之后获取数据用到redux的getState方法,监听仓库数据变化用到subscribe方法,发送请求需要定义一个action,之后调用dispatch方法。这样reducers就会接受到请求从而修改仓库里的数据。

import store from '../../store/index.js';
class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = store.getState();
    store.subscribe(this.storeChange);
  }

  storeChange() {
    this.setState(store.getState());
  }

  inputChange(e) {
    const action = {
      type: "change_input_value",
      inputValue: e.target.value
    }
    store.dispatch(action);
  }
  buttonClick() {
    const action = {
      type: "add_list_item",
      inputValue: this.state.inputValue
    }
    store.dispatch(action);
  }
}

export default TodoList;

优化

统一管理Action,在store下创建两个文件分别是actionTypes和actionCrrators分别用来创建保存Action名和统一生成Action
actionTypes:

export const CHANGE_INPUT_VALUE = "change_input_value";
export const ADD_LIST_ITEM = "add_list_item";
export const CLEAR_LIST_ITEM = "clear_list_item";

actionCrrators:

import { CHANGE_INPUT_VALUE, ADD_LIST_ITEM, CLEAR_LIST_ITEM } from './actionTypes.js';

export const getInputChangeAction = (value) => ({
  type: CHANGE_INPUT_VALUE,
  value
});

export const getAddItemAction = (value) => ({
  type: ADD_LIST_ITEM,
  value
});

export const getClearListItemAction = (index) => ({
  type: CLEAR_LIST_ITEM,
  index
});

这样在使用时就可以直接使用actionCrrators中的方法了:

import { getInputChangeAction, getAddItemAction, getClearListItemAction } from '../../store/actionCrrators.js'
inputChange(e) {
    const action = getInputChangeAction(e.target.value);
    store.dispatch(action);
}

总结

  • store必须是唯一的
  • 只有store能改变自己的内容
  • Reducer必须是纯函数

纯函数指的是,给定固定的输入,就会有固定的输出,而且不会有任何的副总用。

关键API:

  • createStore 创建仓库
  • store.dispatch 发送action请求
  • store.getState 获取仓库内容
  • store.subsccribe 监听仓库变化

未经允许,不可转载