[原创]React Hooks UseReducer 实现撤销前进操作

示例

示例

直接上代码

1. reducer.js

import React from "react";
import _originalUpdate from "immutability-helper";

export const TestDispatch = React.createContext(null);

export const Actions = {
  /**
   * 修改数据
   */
  CHANGE: "CHANGE",
  /**
   * 撤销数据
   */
  UNDO: "UNDO",
  /**
   * 恢复数据
   */
  REDO: "REDO"
};

const originalUpdate = (state, spec) => {
  // _originalUpdate 在不改变原数据的情况下更新数据
  const newState = _originalUpdate(state, spec);
  if (newState.present) {
    window.localStorage.setItem("present", newState.present);
  }
  return newState;
};

const update = (state, spec) => {
  const newPresent = originalUpdate(state.present, Object.assign({}, spec));
  return originalUpdate(state, {
    past: { $push: [state.present] },
    present: { $set: newPresent },
    future: { $set: [] }
  });
};

const undo = state => {
  const lastIndex = state.past.length - 1;
  const last = state.past[lastIndex];
  const present = state.present;
  return originalUpdate(state, {
    past: { $splice: [[lastIndex, 1]] },
    present: { $set: last },
    future: { $unshift: [present] }
  });
};

const redo = state => {
  const firstFuture = state.future[0];
  const present = state.present;
  return originalUpdate(state, {
    past: { $push: [present] },
    present: { $set: firstFuture },
    future: { $splice: [[0, 1]] }
  });
};


export default (state, { type, payload }) => {
  switch (type) {
    case Actions.CHANGE: {
      return update(state, { value: { $set: payload.value } });
    }
    case Actions.UNDO: {
      return undo(state);
    }
    case Actions.REDO: {
      return redo(state);
    }
    default:
      throw new Error();
  }
};

2. App.js

import React, { useReducer } from "react";
import reducer, { Actions, TestDispatch } from "./reducer";

import "./App.css";

export default () => {
  const [state, dispatch] = useReducer(reducer, {
    past: [],
    present: {},
    future: []
  });
  const item = state.present;

  const handleUndo = () => {
    dispatch({
      type: Actions.UNDO
    });
  };

  const handleRedo = () => {
    dispatch({
      type: Actions.REDO
    });
  };

  const handleChange = e => {
    dispatch({
      type: Actions.CHANGE,
      payload: {
        value: e.target.value
      }
    });
  };

  return (
    
      
); };

你可能感兴趣的:([原创]React Hooks UseReducer 实现撤销前进操作)