Support Ukraine 🇺🇦Help Ukrainian ArmyHumanitarian Assistance to Ukrainians

Some inserted text gets ahead of the cursor in SlateJS with React Concurrent Mode

john

Apr 05 2020 at 16:31 GMT

I am using SlateJS with React Concurrent Mode and I find that when I type characters into the editor, some character may get ahead of the cursor and so I end up typing in the middle. This especially happens when typing fast: the more I type, the more characters get ahead of the cursor.

Here's how I am currently using SlateJS to create an editor:

const ExampleEditor = () => {
  const editor = useMemo(() => withReact(createEditor()), [])
  const [value, setValue] = useState([])

  const handleChange = useCallback((newValue) => {
    setValue(newValue)
  }, [])

  return (
    <Slate editor={editor} value={value} onChange={handleChange}>
      <Editable />
    </Slate>
  )
}

This problem occurs only when React Concurrent Mode is enabled. When using React Legacy Mode, this doesn't happen.

Is there a way to fix this?

1 Answer

thoughtful

Apr 05 2020 at 16:48 GMT

This is probably due to the way scheduling works in React Concurrent Mode. From what I understand, each task is given a priority. This includes your state updates, which are batched and given a priority.

Somehow, the batching and scheduling in concurrent mode is messing up your SlateJS editor's state and so you get some characters ahead of the cursor when typing fast.

You can fix this by forcing your value updates to run with immediate priority by using ReactDOM.flushControlled() (currently it's unstable and so it's ReactDOM.unstable_flushControlled()):

const handleChange = useCallback((newValue) => {
  ReactDOM.unstable_flushControlled(() => {
    setValue(newValue)
  })
}, [])
claritician © 2022