簡體   English   中英

使用 react-monaco-editor 正確消除調用 onChange 以進行更新

[英]correctly debouncing a call onChange to update using react-monaco-editor

編輯:

這個問題很好地總結了我的問題:摩納哥編輯器從狀態中獲取當前值,而去抖動防止狀態觸發。 我怎樣才能允許用戶不間斷地繼續輸入而不進行不必要的調用來更新代碼。

-----結束編輯-----

好的,所以我有一個使用 react-monaco-editor 作為代碼編輯器面板的 react 應用程序(沒有 CRA)。 當用戶鍵入 onChange 事件被觸發時,我想調用去抖動更新操作,但這現在不起作用。

設置並不完全直接,但我有一個父組件 CodeEditorPanel,它有一個子組件 monacoEditor。 我已經刪除了盡可能多的與問題沒有直接關系的代碼,但可以根據需要添加更多詳細信息。

在自動模式下使用 updateCode (UPDATE_METHODS.AUTOMATIC.value) 工作得很好,但它的計算成本很高,但是當我使用去抖動模式 (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}
    />
  }

}

我想出了一種對我有用的解決方案,但如果其他人有想法,我仍然很感興趣。

所以我所做的是:

  1. 在我的組件中創建一個本地狀態變量並初始化為代碼道具。
  2. 在 onChange 方法中,我沒有調用動作創建者,而是更新本地狀態。
  3. 我向設置為一秒的組件添加了一個空閑計時器。 所以如果用戶停止輸入一秒鍾,它會調用動作創建者來更新 redux。

我的方法有兩個:

  1. 如果需要立即采取行動(例如代碼完成),那么我會在每次更改時執行任務。

  2. 如果一個動作可以被延遲(例如錯誤檢查),那么實際的變化並不重要。 在這種情況下,我啟動一個計時器(在每次更改時重置)並在觸發后運行所需的操作。 在這種情況下不需要保持狀態,因為它沒有必要。

當然,如果實際更改仍然很重要(例如,將操作限制在自上次運行以來已修改的某個范圍內),那么您當然需要存儲它(或派生值,如范圍)。

React Monaco編輯器

我還有一個想法可以在不調用 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();

  }

單擊保存按鈕,您將獲得編輯器的更新值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM