uiwjs / react-textarea-code-editor

A simple code editor with syntax highlighting.
https://uiwjs.github.io/react-textarea-code-editor/
MIT License
476 stars 22 forks source link

Unable to access ref on CodeEditor using NextJS dynamic #154

Open saleemameen opened 1 year ago

saleemameen commented 1 year ago

Can you please provide an example of how to attach a ref to the CodeEditor component when using NextJS dynamic to load the editor. I get the error:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

I've tried setting up a forwardRef, but can't seem to get the ref assigned.

Thanks :)

jaywcjlove commented 1 year ago

@saleemameen I hope the above issue can help you, I can't help you.

I tried some methods but none of them work

https://codesandbox.io/s/react-textarea-code-editor-example-nextjs-https-github-com-uiwjs-react-textarea-code-editor-issues-154-kpdvfm?file=/pages/index.js

saleemameen commented 1 year ago

@jaywcjlove Thanks for your effort. I think I've managed to come up with a solution that works for anyone that's interested 😊 Please take a look and see if you can reproduce on your end, then maybe you can share in the docs for others?

1. Create a component called WrappedEditor.tsx where you import the CodeEditor normally

import { type Ref } from 'react';
import CodeEditor, { type TextareaCodeEditorProps } from '@uiw/react-textarea-code-editor';

interface WrappedEditorProps extends TextareaCodeEditorProps {
    editorRef: Ref<HTMLTextAreaElement> | undefined;
}

export default function WrappedEditorComponent({ editorRef, ...props }: WrappedEditorProps) {
    return <CodeEditor {...props} ref={editorRef} />;
}

2. Create a component called CodeEditor.tsx where you import the WrappedEditor component dynamically

'use client';
import dynamic from 'next/dynamic';
import React, { useRef } from 'react';
import '@uiw/react-textarea-code-editor/dist.css';

const WrappedEditor = dynamic(() => import('./WrappedEditor'), {
    ssr: false,
});

export default function CodeEditor() {
    const editorRef = useRef<HTMLTextAreaElement | null>(null);
    const [code, setCode] = React.useState(`function add(a, b) {\n  return a + b;\n}`);
    console.log('editorRef', editorRef);
    return (
    <div>
    <WrappedEditor
            value={code}
            language="js"
            placeholder="Please enter JS code."
            onChange={(evn) => setCode(evn.target.value)}
            padding={15}
            editorRef={editorRef}
            style={{
                fontSize: 12,
                backgroundColor: '#f5f5f5',
                fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace',
            }}
    />
    </div>
);
}