编辑:
这个问题很好地总结了我的问题:摩纳哥编辑器从状态中获取当前值,而反跳则阻止状态触发。如何允许用户不间断地继续输入而不进行不必要的调用来更新代码。
-----编辑结束-----
好吧,我有一个使用react-monaco-editor作为代码编辑器面板的react应用程序(没有CRA)。当用户键入时,会触发 onChange 事件,我想调用去抖动更新操作,但这现在不起作用。
设置并不完全简单,但我有一个父组件 CodeEditorPanel,它有一个子组件 monacoEditor。我已经删除了尽可能多与问题不直接相关的代码,但如果需要,可以添加更多详细信息。
在自动模式(UPDATE_METHODS.AUTOMATIC.value)中使用updateCode效果很好,但计算成本很高,但是当我使用去抖模式(UPDATE_METHODS.DEBOUNCE.value)时,更改会变得混乱,看起来像是在使用旧值(听起来就像如果我没有使用 useRef 但我使用了会发生什么。)。无论如何,有些事情(不是那么)显然不对,我将不胜感激任何帮助来发现我的(希望是小)错误。
// CodeEditorPanel.js
import React, { useRef } from 'react';
const CodeEditorPanel = ({
updateMethod, // editor setting, user can choose: automatic, manual, throttled, debounced
updateCode, // the update action I want to debounce
}) => {
const debouncedUpdate = useRef(debounce(updateCode, debounceInterval)).current;
const getUpdateMethod = () => {
switch (updateMethod) {
case UPDATE_METHODS.DEBOUNCE.value:
return debouncedUpdate;
case UPDATE_METHODS.THROTTLE.value:
return throttledUpdate;
case UPDATE_METHODS.MANUAL.value:
return ({ code, selectedFile }) => updateCode({ code, selectedFile, buffer: true });
case UPDATE_METHODS.AUTOMATIC.value:
default:
return updateCode;
}
};
// in reality there is a function call before update getUpdateMethod but I'm trying to simplify
return <MonacoEditor updateCode={getUpdateMethod()} />;
};
//
class monacoEditor extends Component {
onChange(newValue, e) {
const { selectedFile, updateCode } = this.props;
// want to debounce this bad boy right here
updateCode({ code: newValue, selectedFile });
}
render() {
<MonacoEditor
ref="monaco"
language={language}
theme="vs-dark"
defaultValue=""
value={selectedFile.content}
options={MONACO_DEFAULT_OPTIONS}
onChange={this.onChange}
editorWillMount={this.editorWillMount}
editorDidMount={this.editorDidMount}
/>
}
}
我提出了一种适合我的解决方案,但如果其他人有想法,我仍然感兴趣。
所以我所做的是:
我的方法有两个:
如果需要立即采取行动(例如代码完成),那么我会在每次更改时执行任务。
如果某个操作可以延迟(例如错误检查),那么实际的更改并不重要。在这种情况下,我启动一个计时器(每次更改时都会重置)并在触发后运行所需的操作。在这种情况下不需要保持状态,因为没有必要。
当然,如果实际的更改仍然很重要(例如,将操作限制在自上次运行以来修改的某个范围内),那么您当然需要存储它(或派生值,例如范围)。
反应摩纳哥编辑器
我还有一个想法,可以在不调用 onChange 事件的情况下获取 React monacoeditor 值。 创建 MonacoEditor 的引用。
this.editorRef = React.createRef();
之后添加对 MonacoEditor 标签的引用。
<MonacoEditor
ref={this.editorRef}
height="500px"
language="json"
// editorDidMount={this.editorDidMount.bind(this)}
// onChange={this.onChange.bind(this)}
value={this.state.code}
options={options}
/>
然后添加按钮并为 onClick 事件创建函数,如下代码
async saveData(){
const currentCode = this.editorRef.current.editor.getModel().getValue();
this.setState({code:currentCode});
this.editorRef.current.editor?.focus();
}
您将通过单击“保存”按钮获得编辑器的更新值。
我也有同样的问题,我想在编辑器的 onChange 中执行一个函数,它将值写入 url,但它与 onChange 状态发生冲突,并使光标突然移动到编辑器的末尾。
这是我解决问题的方法:
正如@cbutler提到的,首先在我的组件中创建一个本地状态变量并初始化为代码属性。
const [currentConfig, setCurrentConfig] = useState<string>(config);
然后在 onChange 方法中,不调用操作创建者,而是更新本地状态。
const handleEditorChange: OnChange = (value) => {
setCurrentConfig(value || "");
};
<Editor
defaultValue={config}
value={config}
onMount={editorDidMount}
height="100%"
width={"100%"}
defaultLanguage="yaml"
theme="vs-dark"
options={{
quickSuggestions: { other: true, strings: true },
automaticLayout: true,
minimap: { enabled: false },
scrollbar: { verticalScrollbarSize: 5 },
padding: { top: 10 },
}}
onChange={handleEditorChange}
/>
最后添加了这段useEffect代码:
useEffect(() => {
onChangeConfig(currentConfig);
}, [currentConfig]);