Если вы хотите построить инструменты без код, такие как Formblob , один должен быть Особенностью является способность отменить и переделать действия. Почему? Представьте, что вы работали над программным обеспечением для редактирования изображений, и вы внесли несколько изменений в свой холст. Через некоторое время вы понимаете, что то, что у вас было раньше, выглядело намного лучше, чем у вас сейчас. Вы отмените дорогу, пока не дойдете до сцены, которой вы удовлетворяете.
Теперь, если у программного обеспечения не было функции Undo/Redo, вы, скорее всего, выпустили бы немного цветочного языка и навсегда отказались от программного обеспечения.
Итак, как мы можем реализовать функцию Undo/Redo и не допустить, чтобы пользователи отказались от нашего приложения?
Предпосылка
Если вы не знакомы с React Hooks, я предлагаю вам прочитать о них Здесь Анкет Одним из самых фундаментальных крючков является встроенный крюк React Usestate. Это позволяет вам хранить состояние компонента внутри переменной и управлять им по мере необходимости. В этом уроке мы будем писать крючок, который расширяет крюк для использования, чтобы обеспечить функциональность отмены/повторно.
Код
Давайте начнем с кода, а затем я объясню ниже.
import { useMemo, useState } from "react";
// If you're only working with primitives, this is not required
import isEqual from "lodash/isEqual";
export default function useUndoableState(init) {
const [states, setStates] = useState([init]); // Used to store history of all states
const [index, setIndex] = useState(0); // Index of current state within `states`
const state = useMemo(() => states[index], [states, index]); // Current state
const setState = (value) => {
// Use lodash isEqual to check for deep equality
// If state has not changed, return to avoid triggering a re-render
if (isEqual(state, value)) {
return;
}
const copy = states.slice(0, index + 1); // This removes all future (redo) states after current index
copy.push(value);
setStates(copy);
setIndex(copy.length - 1);
};
// Clear all state history
const resetState = (init) => {
setIndex(0);
setStates([init]);
};
// Allows you to go back (undo) N steps
const goBack = (steps = 1) => {
setIndex(Math.max(0, Number(index) - (Number(steps) || 1)));
};
// Allows you to go forward (redo) N steps
const goForward = (steps = 1) => {
setIndex(Math.min(states.length - 1, Number(index) + (Number(steps) || 1)));
};
return {
state,
setState,
resetState,
index,
lastIndex: states.length - 1,
goBack,
goForward,
};
}
Концепция
Как и в случае с Usestate, useundoablestate принимает только 1 аргумент, начальное значение. За кулисами крюк использует две основные переменные для определения состояния – Индекс (номер) и Государства (множество). Государства хранят исторические ценности государства, пока Индекс Определяет текущее состояние, указав текущую позицию в массиве.
Вы можете перемещаться по историческим состояниям, используя Goback и Goforward функции, испускаемые крючком. Однако, если вы позвоните SetState и Индекс не в конце Государства массив, все штаты после Индекс стерто и Индекс Вернется к концу состояния множество. Другими словами, как только вы позвоните SetState , вы больше не можете повторить.
Следующая таблица пытается дать более подробное объяснение объекта, возвращаемого крючком:
| штат | Любые | Текущее состояние, инициализированное с принятым аргументом | |
| Setstate | фанк | SetState (значение) | Устанавливает состояние в стоимость. Все значения после текущего индекса стерли |
| Сброс | фанк | ResetState (значение) | Удаляет исторические состояния и сбрасывается в ценность |
| показатель | количество | Текущий индекс в массиве штатов | |
| Lastindex | количество | Последний индекс в массиве штатов. Может быть использован, чтобы определить, может ли GoForward. < Lastindex | |
| вернитесь назад | фанк | Goback (2) | Возвращается количество прошлых шагов |
| иди вперед | фанк | Goforward (3) | Продолжает количество пройденных шагов |
использование
import React from "react";
import useUndoableState from "path/to/hook";
const init = { text: "The quick brown fox jumps over the lazy dog" };
export default function Document() {
const {
state: doc,
setState: setDoc,
resetState: resetDoc,
index: docStateIndex,
lastIndex: docStateLastIndex,
goBack: undoDoc,
goForward: redoDoc
} = useUndoableState(init);
const canUndo = docStateIndex > 0;
const canRedo = docStateIndex < docStateLastIndex;
return (
);
}
Заключительные замечания
С функциональностью Undo/Refo, Formblob является одним из избранных строителей формы без кода, который дает вам гибкость для редактирования ваших форм без страха потерять предыдущее состояние. Как инструмент без кода, FormBlob позволяет любому создавать и публиковать потрясающие формы и опросы за 2 минуты. Попробуйте это бесплатно сегодня!
Оригинал: “https://dev.to/jeremyling/react-hook-to-allow-undoredo-4poj”