uiwjs / react-monacoeditor

Monaco Editor component for React.
https://uiwjs.github.io/react-monacoeditor/
MIT License
296 stars 26 forks source link

When the {value} is provided again, with the same value, the position returns to the beggining of the file. #65

Closed gissehel closed 3 years ago

gissehel commented 3 years ago

I'm trying to MonacoEditor with redux. Which means that the text in the editor is stored in the redux store.

On each key, the new value of the text is presented to the MonacoEditor React componant. And it's working fine, but the "position" of the cursor keep beeing reseting the beggining of the file.

Is there a way to configure the component so the position doesn't change when presenting a new value (or at least the same value as the one already in the editor) ?

jaywcjlove commented 3 years ago

Use shouldComponentUpdate() to let React know if a component’s output is not affected by the current change in state or props.

@gissehel

shouldComponentUpdate(nextProps, nextState)
gissehel commented 3 years ago

Thanks !

The docs says that it's optimisation only and I should not rely on that to render or not, so I've used that call to test if I should update or not:

    shouldComponentUpdate(nextProps) {
        if (this._editor) {
            const editorText = this._editor.editor.getValue();
            const nextPropsText = nextProps.text;

            if (nextPropsText === editorText) {
                this.shouldUpdate = false;
            } else {
                this.shouldUpdate = true;
            }
            return this.shouldUpdate;
        } else {
            return true;
        }
    }

But because I should not rely on this call to render or not, I've also added in the render section, the fact that value gets null if shouldUpdate is false.

    render() {
        const { text, onTextChanged } = this.props;
        const { shouldUpdate } = this;

        return <div className='Editor'>
            <MonacoEditor
                className='MonacoEditor'
                ref={(ref) => this._editor = ref}
                language="plaintext"
                onChange={onTextChanged}
                value={shouldUpdate ? text : null}
                options={{
                    theme: 'vs',
                    automaticLayout: false,
                }}
                height='700px'
            />
        </div>
    }

And with shouldUpdate being defined as:

    get shouldUpdate() {
        return this._shouldUpdate === undefined ? true : this._shouldUpdate
    }

    set shouldUpdate(value) {
        this._shouldUpdate = value;
    }

in order to be sure that if shouldUpdate has never been set, it should update.

I'm not really sure that it's the shortest, nicest or cleanest solution (as I'm mainly writing stateless react component, I'm almost only doing render stuff), but it's working.