Цель, которую я хочу достичь, - реализовать функцию автосохранения без ущерба для производительности (бесполезные повторные рендеры и т. д.). В идеале, когда произойдет автосохранение, состояние тоже будет обновлено. Я создал пример компонента с 3 входами, в этом примере компонент перерисовывается при каждом нажатии клавиши. У меня также есть хук useEffect, в котором я ищу изменения данных, а затем сохраняю их через 1 секунду. ChildComponent используется для предварительного просмотра входных данных.
function App(props) {
const timer = React.useRef(null);
const [data, setData] = React.useState(props.inputData);
React.useEffect(() => {
clearTimeout(timer.current)
timer.current = setTimeout(() => {
console.log("Saving call...", data)
}, 1000)
}, [data])
const inputChangeHandler = (e, type) => {
if (type === "first") {
setData({ ...data, first: e.target.value })
} else if (type === "second") {
setData({ ...data, second: e.target.value })
} else if (type === "third") {
setData({ ...data, third: e.target.value })
}
}
return (
<>
<div className="inputFields">
<input
defaultValue={data.first}
type="text"
onChange={(e) => inputChangeHandler(e, "first")}
/>
<input
defaultValue={data.second}
type="text"
onChange={(e) => inputChangeHandler(e, "second")}
/>
<input
defaultValue={data.third}
type="text"
onChange={(e) => inputChangeHandler(e, "third")}
/>
</div>
<ChildComponent data={data} />
</>
)
}
Я читал о debounce, но моя реализация не сработала. Кто-нибудь сталкивался с такой же проблемой?
Ниже приведена моя реализация debounce с использованием lodash:
React.useEffect(() => {
console.log("Saving call...", data)
}, [data])
const delayedSave = React.useCallback(_.debounce(value => setData(value), 1000), []);
const inputChangeHandler = (e, type) => {
if (type === "first") {
let obj = { ...data };
obj.first = e.target.value;
delayedSave(obj)
} else if (type === "second") {
let obj = { ...data };
obj.second = e.target.value;
delayedSave(obj)
} else if (type === "third") {
let obj = { ...data };
obj.third = e.target.value;
delayedSave(obj)
}
}
Проблема с этим заключается в том, что если пользователь вводит сразу (до задержки в 1 секунду) с первого ввода на второй, он сохраняет только последний ввод пользователя.
setData
является асинхронным, данные не будут обновляться немедленно. - person Beyond   schedule 03.08.2020