在 useState 值更新后更新组件

Update a component after useState value updates

在 React 组件中有一个 monaco 编辑器:

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

defaultValue,编辑器内部的默认代码,通过 props 发送到组件:

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

当用户编辑代码时,onChange={onChangeCode}被调用:

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

我的问题是,当用户点击 Cancel 时,如何将代码重置为原始代码?

最初是这样的:

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

但它没有用,可能是因为 useState 是异步的,有什么解决办法吗?

这里是整个组件的更多上下文:

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;

如果您需要能够从外部更改值,则需要通过传递 value 属性 (sandbox) 将 Editor 用作受控组件:

例如:

const defaultValue = "// let's write some broken code ";

function App() {
  const [value, setValue] = useState(defaultValue);

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

  return (
    <>
      <button title="cancel" onClick={handleCancel}>
        Cancel
      </button>

      <Editor
        value={value}
        onChange={setValue}
        height="90vh"
        defaultLanguage="javascript"
      />
    </>
  );
}