jsoneditor icon indicating copy to clipboard operation
jsoneditor copied to clipboard

React function component: Cannot read property 'catch' of undefined

Open xyxc0673 opened this issue 3 years ago • 8 comments

Hi, thanks for the great job. I am using jsoneditor with react and function component. Everything goes fine, but when I trigger updating using onChangeJSON and then an error thrown.

Cannot read property 'catch' of undefined

Demo code: https://codesandbox.io/s/9sljv

xyxc0673 avatar Jul 29 '21 09:07 xyxc0673

Hi, thanks! It looks like your demo code is incomplete: the file editor.jsx containing the CustomJSONEditor is empty.

Have you seen the React examples that come with the library? See:

  • https://github.com/josdejong/jsoneditor/tree/develop/examples/react_demo
  • https://github.com/josdejong/jsoneditor/tree/develop/examples/react_advanced_demo

josdejong avatar Jul 30 '21 14:07 josdejong

@josdejong Sorry, I forgot to save the files and have added sample codes now. I have seen the examples and want to make it with React Hooks.

xyxc0673 avatar Aug 02 '21 01:08 xyxc0673

Ah, now I get something: I get an error "this.validate() is undefined".

I think the cause is that in your code example, with every change in your json, you destroy the editor and create a new one. It would be good if the editor is robust against this and doesn't give this error (this.validate() is running in a debounced function, and when it executes, the editor is destroyed already). But anyway you should make sure the editor is only instantiated once, else you will lose your state (scroll bar position, cursor, expanded nodes, etc) with every change you make, which is not workable.

josdejong avatar Aug 02 '21 12:08 josdejong

Thanks @josdejong It works when I remove the destroy code in the useEffect, and I am now wondering if I have to destroy the instance when the page unmounts.

xyxc0673 avatar Aug 03 '21 08:08 xyxc0673

Yes normally you have to destroy the instance when your component unmounts. If you don't do that, you can get memory leakage (holding more and more jsoneditors in memory).

josdejong avatar Aug 07 '21 07:08 josdejong

@josdejong, @xyxc0673, would you let me know what is the final solution?

marindrag avatar Sep 30 '21 12:09 marindrag

export const JsonEditor: FC<IJsonEditorProps> = memo(
  ({ schema, mode, initialJsonValue, onChange }: IJsonEditorProps) => {
    const validate = ajv.compile(schema)

    const containerRef = useRef<HTMLDivElement | null>(null)

    const editorRef = useRef<JSONEditor | null>(null)

    const handleChange = () => {
      console.log(onChange)
      if (onChange && editorRef.current && validate) {
        let json = editorRef.current.get()
        const isJsonValid = validate(json)
        if (isJsonValid) {
          onChange(json)
        } else {
          onChange(null)
        }
      }
    }

    useEffect(() => {
      if (containerRef.current != null) {
        console.log("here", containerRef.current, editorRef.current)
        if (editorRef.current != null) {
          editorRef.current.setSchema(schema)
          editorRef.current.set(initialJsonValue)
          if (mode) {
            editorRef.current.setMode(mode)
          }
        } else {
          editorRef.current = new JSONEditor(containerRef.current, {
            schema: schema,
            mode: "tree",
            indentation: 4,
            onChange: handleChange,
          })
          editorRef.current.set(initialJsonValue)
        }
      }
    }, [containerRef, initialJsonValue, schema, mode])

    useEffect(() => () => {
      editorRef.current?.destroy()
    }, [])

    return (
      <div
        className="jsoneditor-react-container"
        ref={containerRef}
      />
    )
  }
)

marindrag avatar Sep 30 '21 12:09 marindrag

Thanks for sharing your solution @marindrag

A bit off-topic: I haven't worked out an example with react hooks for jsoneditor, but did so for the successor, svelte-jsoneditor: https://codesandbox.io/s/svelte-jsoneditor-react-59wxz?file=/src/SvelteJSONEditor.js which as an API which is better aligned to use within React or an other framework.

josdejong avatar Oct 02 '21 08:10 josdejong