react-codemirror icon indicating copy to clipboard operation
react-codemirror copied to clipboard

Using this as a "controlled" component?

Open wardellbagby opened this issue 3 years ago • 8 comments

Is it possible to move the state out of the React component and instead always provide it as a prop? I.e., making it controlled vs its current uncontrolled?

https://reactjs.org/docs/uncontrolled-components.html https://reactjs.org/docs/forms.html#controlled-components

wardellbagby avatar Feb 20 '22 20:02 wardellbagby

Which states need to be removed and used as props? @wardellbagby

jaywcjlove avatar Feb 21 '22 00:02 jaywcjlove

To make it a controlled component?

Well, that's kind of where the issue is; I'm not entirely sure.

What I'm looking for is a way to just give this an EditorState and let the component render that EditorState to an EditorView.

That itself is really simple, but solving issues like "is this a brand new state and therefore should use setState or should it be dispatched as an array of Transactions has be pretty unsure. So I wanted to see if y'all had any thoughts around it?

wardellbagby avatar Feb 21 '22 02:02 wardellbagby

also interested in controlling state from outside of this component; in particular, managing the value to validate code externally, and a few other props to dynamically add and style elements within the editor (error messages in gutters, etc)

one issue i'm seeing with the controlled flow is: whenever a prop passed into useCodeMirror is changed, there's a flash from an unmount & remount of the autocompletion tooltip

here's a repro where you can see the behavior – in this case, each keystroke when typing to change the value of the controlled component causes a flash (type 'func' to get the relevant js autocomplete)

this may be an issue with or improper usage of core codemirror packages (perhaps here in the TooltipViewManager?), but curious if anyone has a similar use case, a fix at either the react-codemirror or codemirror-level, or any other thoughts, i'd love to hear!

sfmcintyre avatar Mar 08 '22 23:03 sfmcintyre

Is it possible to move the state out of the React component and instead always provide it as a prop? I.e., making it controlled vs its current uncontrolled?

Did you have any luck in doing so in the meanwhile?

tomerlichtash avatar Jan 24 '23 13:01 tomerlichtash

Same here. I need a "controlled" <CodeMirror> component.

the-watchmaker avatar Mar 03 '23 05:03 the-watchmaker

@the-watchmaker Turns out there're not many open source solutions out there for a well behaved controlled CM in React. After some research I ended up following a this article as a guide, using a custom onChange method and a hook to achieve a controlled state.

tomerlichtash avatar Mar 03 '23 08:03 tomerlichtash

@tomerlichtash Thanks for the link. I solved most of the issues by using EditorState.changeFilter and EditorState.transactionFilter in extensions prop to filter or mutate the input.

Lilke this:

<CodeMirror
    //...
    extensions={[
      EditorState.changeFilter.of(handleLimitDocLength),
    ]}
  />

I think most of time this is what we want to achieve as a React dev User input -> update input state -> mutate input state using useMemo or useEffect -> update input state -> rerender with thew new input

But my workaround in this case with Codemirror was: User input -> intercept input and do your stuff with EditorState.changeFilter and EditorState.transactionFilter -> update state -> rerender

This is a typical case where not everything is in React way. Especially when you work with libs that came before it.

I find 90% of the time, DIY React integration with the 3rd party lib is the way to go. But this was for my pet project. I wouldn't bother.

the-watchmaker avatar Mar 03 '23 17:03 the-watchmaker