我正在尝试消除对更新 codemirror 的调用。它有点“有效”,但问题是编辑器的值直到 debounce 调用之后才更新(根本)。因此,即使我按下空格键,光标位置也不会更新,直到去抖动调用完成。
debounced call 是一个动作创建者,它流经多个 sagas、reducer 并最终更新在应用程序中产生明显延迟的组件。有没有办法做到这一点,以便用户可以继续打字而不会出现这种延迟?
编辑:
这个问题很好地总结了我的问题:代码镜像从状态中获取值,而去抖动防止状态触发。
代码:
const cmEditor = ({ selectedFile, updateCode }) => {
const debounced = useCallback(
_.debounce((code, selectedFile) => { updateCode({ code, selectedFile }); }, 1000),
[],
);
const update = (editor, data, code) => {
debounced(code, selectedFile);
};
return (
<Container>
<CodeMirror
value={selectedFile.content}
options={{ ...CODE_MIRROR_DEFAULT_OPTIONS, mode: getCodeMode(EDITORS.CODE_MIRROR.value, selectedFile.mimeType) }}
onBeforeChange={(editor, data, code) => update(editor, data, code)}
/>
</Container>
);
};
cmEditor.propTypes = {
selectedFile: PropTypes.object.isRequired,
updateCode: PropTypes.func.isRequired,
};
export default cmEditor;
编辑2:
这是我使用本地状态和空闲计时器的实现。不太工作,但几乎:
const cmEditor = ({ selectedFile, updateCode }) => {
const [idleTimer, setIdleTimer] = useState(1);
const [localCode, setLocalCode] = useState(selectedFile.content);
useEffect(() => {
setLocalCode(selectedFile.content);
}, [selectedFile.content]);
// Add event listeners
useEffect(() => {
window.addEventListener('mousemove', resetIdleTimer);
window.addEventListener('keypress', resetIdleTimer);
// Remove event listeners on cleanup
return () => {
window.removeEventListener('mousemove', resetIdleTimer);
window.removeEventListener('keypress', resetIdleTimer);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
useEffect(() => {
let timer = null;
timer = setTimeout(() => {
if (idleTimer === 0) {
handleUpdate();
clearTimeout(timer);
// resetIdleTimer();
} else {
setIdleTimer(idleTimer - 1);
}
}, 1000);
return () => clearTimeout(timer);
}, [idleTimer]);
const resetIdleTimer = () => setIdleTimer(DEFAULT_IDLE_TIMEOUT);
const handleUpdate = () => updateCode({ code: localCode, selectedFile });
return (
<Container>
<CodeMirror
value={localCode}
options={{ ...CODE_MIRROR_DEFAULT_OPTIONS, mode: getCodeMode(EDITORS.CODE_MIRROR.value, selectedFile.mimeType) }}
onBeforeChange={(editor, data, code) => setLocalCode(code)}
/>
</Container>
);
};