Skip to content

Using editor.addCommand in onMount the handler doesn't see actual value from state #427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
vladtimss opened this issue Nov 23, 2022 · 4 comments

Comments

@vladtimss
Copy link

vladtimss commented Nov 23, 2022

Hello! Many thanks for this project!

I have a component which has a state. in onMount i passed a callback with two params (editor, monaco).

Then in onMount i can set editor.addCommand

ok

const App = () => {
    const [bool, setBool] = useState(false); // by default false, but imagine user in some time click on button and changed the 
                                                                           // value on true
    const myFunc = () => {
        console.log(value) // expected true
    };

    const handleEditorDidMount = (editor, monaco) => {
         editor.addCommand(monaco.KeyMod.Shift | monaco.KeyCode.Enter | monaco.KeyMod.CtrlCmd, myFunc);
    };

    return (
             <Editor
                value={value}
                onChange={handleEditorChange}
                onMount={handleEditorDidMount}
            />
    )
}

myFunc see always first value of Bool as false, and if the component will be updated, the trigger command will be use old not updated value of Bool

What incorrect i do? How should i use addCommand Correctly?

@chl3188
Copy link

chl3188 commented Mar 2, 2023

I'm having the same problem.
Did you solve it?

@vladtimss
Copy link
Author

vladtimss commented Mar 2, 2023

I'm having the same problem. Did you solve it?

Now, i solved this problem with timestamp and useEffect

i did a few steps

  1. added one more useState for timestamp [timestamp, setTimeStamp] = useState()
  2. created useEffect which depends on timestamp
    useEffect(() => { // here i update value }, [timestamp])

if you need pass some params to update value, you could put in useState with timestamp object (i did { timestamp, event })
3) create callback editor.onKeyDown(editorOnKeyDown); which accept event and catch firing need you keys, then setTimestamp({timestamp: new Date().getTime(), event: event}) in your callback
4) so that you can add some logic in useEffect to update your value

But im sorry if this solution not is good. But at the same time i have no more ideas

@jetaggart
Copy link

What's even stranger is if you say editor.value it will be the original value. This feels like it's breaking the rules of javascript but I'm not sure how. If you close over a local variable, such as a useState, it somehow is stuck on the original value as mentioned above. How is that even possible?

@dinghar
Copy link

dinghar commented Jan 29, 2025

Looking at the source it seems there's an overuse of React memo calls. I published a version of this package that removes the offending calls https://www.npmjs.com/package/monaco-react-editor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants