我想要实现的目标是实现自动保存功能而不损害性能(无用的重新渲染等)。 理想情况下,当自动保存发生时,状态也会更新。 我创建了一个具有 3 个输入的示例组件,在此示例中,该组件在每次击键时都会重新渲染。我还有一个 useEffect Hook ,在其中查找数据更改,然后在 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} />
</>
)
}
我读过有关去抖动的内容,但我的实现不起作用。有人遇到同样的问题吗?
下面是我使用 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 秒延迟之前)键入,则只会保存最后一个用户输入。
最佳答案
您的实现中的问题是,计时器是使用组件之前的数据
在闭包中设置的(在useEffect
中)计时器启动。一旦data
(或我的实现提案中的newData
)发生更改,您应该启动计时器。像这样的东西:
function App(props) {
const [data, setData] = React.useState(props.inputData);
const { current } = React.useRef({ data, timer: null });
const inputChangeHandler = (e, type) => {
current.data = { ...current.data, [type]: e.target.value };
if(current.timer) clearTimeout(current.timer);
current.timer = setTimeout(() => {
current.timer = null;
setData(current.data);
console.log("Saving...", current.data);
}, 1000);
}
return (
<>
<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")} />
</>
);
}
关于ReactJS - 具有多个输入的自动保存 - 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63234259/