3

I have been trying to integrate the JSONEditor into a React TypeScript application. The working sample of React JavaScript version is available at https://github.com/josdejong/jsoneditor/blob/master/examples/react_demo/src/JSONEditorDemo.js (and reproduced below). I have since ported the code into React TypeScript as under. Am I doing the right thing? Are any further improvements recommended?

React JavaScript version

import React, {Component} from 'react';
import JSONEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.css';
import './JSONEditorDemo.css';

export default class JSONEditorDemo extends Component {
  componentDidMount () {
    const options = {
      mode: 'tree',
      onChangeJSON: this.props.onChangeJSON
    };

    this.jsoneditor = new JSONEditor(this.container, options);
    this.jsoneditor.set(this.props.json);
  }

  componentWillUnmount () {
    if (this.jsoneditor) {
      this.jsoneditor.destroy();
    }
  }

  componentDidUpdate() {
    this.jsoneditor.update(this.props.json);
  }

  render() {
    return (
        <div className="jsoneditor-react-container" ref={elem => this.container = elem} />
    );
  }
}

React TypeScript version

export const Editor = (props: IProps) => {
  
    const mode : JSONEditorMode = "tree";
    const elRef = React.useRef<HTMLDivElement | null>(null);
    const editorRef = React.useRef<JSONEditor | null>(null);
    
    const unmountEditor = () => {
        editorRef.current?.destroy();
    }

  React.useEffect(() => {
    //const container = document.getElementById("jsoneditor");
    const container = elRef.current;
    const options : JSONEditorOptions = {
        mode: mode,
        onChangeJSON: props.onChangeJSON,
    };

    if (container) { 
      const jsonEditor =  new JSONEditor(container, options);
      jsonEditor.set(props.json);
      editorRef.current = jsonEditor;
    }

    return unmountEditor;
  }, [props]);
  
    return <div id="jsoneditor" ref={elRef} className="jsoneditor-react-container" />;
  };
skyboyer
  • 22,209
  • 7
  • 57
  • 64
CONCON
  • 81
  • 1
  • 2
  • 1
    it's almost perfect, i think `const mode : JSONEditorMode = "tree";` is not necessary. add mode inside `options`, but it's good! – b3hr4d Jan 19 '21 at 12:21
  • Maybe add a null coalescing check to `editorRef.current?.destroy();` => `editorRef?.current?.destroy();` since `editorRef ` is null at initialization. Also for `elRef.current` to avoid null reference exceptions. – Stutje Jan 19 '21 at 16:13
  • You can also use `const elRef = React.useRef();`. Which stands for `const elRef = React.useRef(undefined);` but it's a bit shorter and cleaner :) – Stutje Jan 19 '21 at 16:15
  • @Stutje, it is correct to unmount within useEffect that contains `dependancies` or better to unmount in a separate `useEffect` with empty dependancy array? – Asking Mar 28 '22 at 11:37
  • @Asking you can return an parameterless function in each useEffect, which acts as clean up. useEffect without wihtout dependencies act like onMounted event and the function you return acts like onUnmount event. More info https://stackoverflow.com/a/53465182/9124424 – Stutje Mar 31 '22 at 17:52

0 Answers0