0

我正在尝试消除对更新 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>
  );
};
4

1 回答 1

0

我对 React 不太熟悉,但我认为这些更改只有在函数完成update才能看到,其中包括去抖动时间。您可以通过用 标记更新函数来使函数异步async,但我不知道这是否会对您的框架产生任何副作用:

  const update = async (editor, data, code) => {
    debounced(code, selectedFile);
  };

作为替代方案,您可以考虑使用onChange触发器而不是onBeforeChange,因为它会在执行您的语句之前首先处理用户的交互。

于 2020-10-18T18:26:59.507 回答