How do I use `react-hook-form` with `proseMirror` editor?

how do I use react-hook-form together with proseMirror editor?

Below is my attempt to integrate react-hook-form with proseMirror:

import {EditorState} from "prosemirror-state"
import {EditorView} from "prosemirror-view"
import {Schema, DOMParser} from "prosemirror-model"
import {schema} from "prosemirror-schema-basic"
import {addListNodes} from "prosemirror-schema-list"
import {exampleSetup} from "prosemirror-example-setup"

import { useForm } from "react-hook-form";

function Page() {

    const { register, handleSubmit } = useForm();
    const onSubmit = data => console.log(data);

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
    
            <div style={}>
        
                <div>
        
                    <label className="c-label-block">Message</label>
        
                    <div id="editor" {...register("editor")}></div>
                    <div id="content"></div>
        
                </div>
        
            </div>
       
        
            <div className="c-btn-group c-btn c-btn-primary c-btn--medium" onClick={handleSubmit(onSubmit)}>
                <div tabIndex={0}>Submit</div>
            </div>
        
    
    	</form>
	);
    
}

but when I click submit button I am getting:

Unhandled Runtime Error
TypeError: Cannot read property 'split' of undefined at get (index.esm.js:28)

seems that react-hook-form cannot retrieve the value inside the proseMirror editor, how do I retrieve the input value from proseMirror editor?

@Yelnya I’m not sure what exactly you are doing, but you can’t embed the React component into PM doc, make a Plugin or NodeView that pops out a modal where you render your React form with either ReactDOM.render or createPortal. Or if you really insist embedding the form inside your doc, you can use your custom ReactNodeView to wrap a NodeView into a React component. Or you can just make the form the old-fashioned eye without React. If you want to submit your PM doc as a react-hook-form form-field, just retrieve the PM doc from the view.state in your onSubmit handler and do your validation.

That’s my 2 cents.

I forgot to include the useEffect() code in the question above:

    /*
    |--------------------------------------------------------------------------
    | Use Effect
    |--------------------------------------------------------------------------
    */
    useEffect(() => {

        // Mix the nodes from prosemirror-schema-list into the basic schema to
        // create a schema with list support.
        const mySchema = new Schema({
            nodes: addListNodes(schema.spec.nodes, "paragraph block*", "block"),
            marks: schema.spec.marks
        })

        window.view = new EditorView(document.querySelector("#editor"), {
            state: EditorState.create({
                doc: DOMParser.fromSchema(mySchema).parse(document.querySelector("#content")),
                plugins: exampleSetup({schema: mySchema}),
            })
        })

I just cant wrap my head around how this editor works, it is very confusing and not as good as the other editors like tinymce and ckeditor, it is far easier to customize the editor options for these other plugins compared to prosemirror

I stumbled across this post: https://discuss.prosemirror.net/t/lightweight-react-integration-example/2680

but I still dont understand what it is doing

Well I can’t say that the learning curve isn’t steep. But you can think of it as the minimal layer for rich-text editing where you still are left to deal with a lot of minute details that require deeper understanding of DOM and its behavior. It might seem confusing but that’s how DOM works. For simple stuff, I think you should pick an easier editor to use. Especially if you are just making simple forms with rich-text content. Or use a PM-based framework.

But if you want to stick with PM, I recommend forgoing the need of making all things React-based. PM is much easier to use when you handle the rendering of DOM yourself and wrap them as React components only when absolutely necessary. I think there’s material out there to help you understand PM and how to integrate it with React, if you so desire.

To go back to your example, if you want to make it more Reacty use a ref to point to the editor element and store the view in a store. Add your own dispatchTransaction method and there you can trigger a callback to sync the EditorState with the React state.