'Update a component after useState value updates

Having a monaco-editor inside a React component:

<Editor defaultValue={defaultValue} defaultLanguage='python' onChange={onChangeCode} />

The defaultValue, the default code inside of the editor, is sent via props to the component:

const MyComponent = ({
  originalCode
}: MyComponentProps) => {
  const [defaultValue, setDefaultValue] = useState(originalCode);

When the user edits the code, onChange={onChangeCode} is called:

  const onChangeCode = (input: string | undefined) => {
    if (input) {
      setCode(input);
    }
  };

My question is, how to reset the code to the original one when the user clicks on Cancel?

Initially it was like:

  const handleCancel = () => {
    onChangeCode(defaultValue);
  };

but it didn't work, probably because useState is asynchronous, any ideas how to fix this?

Here is the whole component for more context:

import Editor from '@monaco-editor/react';
import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';

import { Button, HeaderWithButtons } from '../shared/ui-components';

import { ICalculationEngine } from '../../../lib/constants/types';
import { usePostScript } from '../../../lib/hooks/use-post-script';
import { scriptPayload } from '../../../mocks/scriptPayload';
import { editorDefaultValue } from '../../../utils/utils';
export interface ScriptDefinitionProps {
  realInputDetails: Array<ICalculationEngine['RealInputDetails']>;
  realOutputDetails: ICalculationEngine['RealInputDetails'];
  originalCode: string;
  scriptLibId: string;
  data: ICalculationEngine['ScriptPayload'];
}

const ScriptDefinition = ({
  realInputDetails,
  realOutputDetails,
  originalCode
}: ScriptDefinitionProps) => {
  const [defaultValue, setDefaultValue] = useState(originalCode);
  const [code, setCode] = useState(defaultValue);
  const { handleSubmit } = useForm({});
  const { mutate: postScript } = usePostScript();
  const handleSubmitClick = handleSubmit(() => {
    postScript(scriptPayload);
  });
  const handleCancel = () => {
    onChangeCode(defaultValue);
  };

  const onChangeCode = (input: string | undefined) => {
    if (input) {
      setCode(input);
    }
  };

  useEffect(() => {
    setDefaultValue(editorDefaultValue(realInputDetails, realOutputDetails));
  }, [realInputDetails, realOutputDetails, originalCode]);

  return (
    <div>
      <HeaderWithButtons>
        <div>
          <Button title='cancel' onClick={handleCancel} />
          <Button title='save' onClick={handleSubmitClick} />
        </div>
      </HeaderWithButtons>
      <Editor defaultValue={defaultValue} defaultLanguage='python' onChange={onChangeCode} />
    </div>
  );
};

export default ScriptDefinition;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source