Redux入门

Redux 入门

使用 Redux 重构之前的 TodoList,使用全局 state 来实现。

Redux Flow

Redux 的工作流:
Redux Flow

一、引入依赖

需要先引入 Ant Design 和 Redux

yarn add antd
yarn add redux

二、创建全局 Store

第一步:创建 store/reducer.js
reducer 必须返回一个函数,state 参数为存储的内容

const defaultState = {
  // state默认值
  inputValue: "123",
  list: [1, 2, 3]
};

export default (state = defaultState, action) => {
  return state;
};

第二步:创建 store/index.js
使用 redux 的 createStore 方法,使用之前创建的 reducer 作为参数,创建一个 store

import { createStore } from "redux";
import reducer from "./reducer";

const store = createStore(reducer);

export default store;

使用与修改

一:使用 redux 的公共存储

import store from "./store/index.js";
// import store from './store' // 可以缩写为这样

console.log(store.getState()); // 直接能打印出store中的内容

二:修改 redux 中的内容

注意:redux 的 reducer 只支持读取 state,而不支持修改 state。如果需要修改,请深拷贝原有 state,修改新的 newState,并将 newState 返回。

const defaultState = {
  inputValue: "Hello React !",
  list: ["1111", "2222"]
};

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

三、监听 store 内容的修改

    constructor(props) {
        super(props);
        this.state = store.getState();
        this.handleStoreChange = this.handleStoreChange.bind(this);
        store.subscribe(this.handleStoreChange);
    }

    render () {
        ...
    }

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

整体使用如下:

src/TodoList.js

import React, { Component } from "react";
import store from "./store";
import "antd/dist/antd.css";
import { Input, Button, List } from "antd";
import {
  getInputChangeAction,
  getAddItemAction,
  getDeleteItemAction
} from "./store/actionCreator";

class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = store.getState();
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleStoreChange = this.handleStoreChange.bind(this);
    this.handleBtnClick = this.handleBtnClick.bind(this);
    this.handleDeleteItem = this.handleDeleteItem.bind(this);
    store.subscribe(this.handleStoreChange);
  }

  render() {
    return (
      <div style={{ marginTop: "10px", marginLeft: "10px" }}>
        <Input
          style={{ width: "300px", marginRight: "10px" }}
          value={this.state.inputValue}
          onChange={this.handleInputChange}
        />
        <Button type="primary" onClick={this.handleBtnClick}>
          �交
        </Button>
        <br />
        <List
          style={{ width: "300px" }}
          bordered
          dataSource={this.state.list}
          renderItem={(item, index) => (
            <List.Item onClick={() => this.handleDeleteItem(index)}>
              {item}
            </List.Item>
          )}
        />
      </div>
    );
  }

  handleInputChange(e) {
    const value = e.target.value;
    const action = getInputChangeAction(value);
    store.dispatch(action);
  }

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

  handleBtnClick() {
    const action = getAddItemAction();
    store.dispatch(action);
  }

  handleDeleteItem(index) {
    const action = getDeleteItemAction(index);
    store.dispatch(action);
  }
}

export default TodoList;

src/store/index.js

import { createStore } from "redux";
import reducer from "./reducer";

const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

export default store;

src/store/reducer.js

const defaultState = {
  inputValue: "Hello React !",
  list: ["1111", "2222"]
};

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

src/store/actionTypes.js

将所有的 Action 类型提取为常量,统一管理。方便调试与代码定位。

export const CHANGE_INPUT_VALUE = "change_input_value";
export const ADD_LIST_ITEM = "add_list_item";
export const DEL_LIST_ITEM = "del_list_item";

src/store/actionCreator.js

将 Action 的创建统一管理,使用 Creator 提供创建 Action 的方法。使流程更加清晰

import {
  CHANGE_INPUT_VALUE,
  ADD_LIST_ITEM,
  DEL_LIST_ITEM
} from "./actionTypes";

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

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

export const getDeleteItemAction = index => ({
  type: DEL_LIST_ITEM,
  index: index
});
文章作者: koral
文章链接: http://luokaiii.github.io/2019/05/08/读书笔记/《React》简书慕课/2.ReduxFlow/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自