Search code examples
javascriptreactjs

Cant get coderef.current in my main index.js file and it is bringing an error


So I have 2 of these, I should get the codeRef.current from EditorContainer.js to index.js but I am not getting it What can i do

here is index.js

import { useNavigate, useParams } from "react-router-dom";
import "./playground.scss";
import codelogo from "./vlogo.png";
import { PlaygroundContext } from "../../Providers/PlaygroundProvider";
import { Navigate } from "react-router-dom";
import { EditorContainer } from "./EditorContainer";
import { useContext } from "react";

export const PlaygroundScreen = () =>{
   
    const {saveCode} = useContext(PlaygroundContext);

    const Navigate = useNavigate();

    const homepage = () => {
        Navigate(`/`);
    }

    const onSaveCode = () => {
        saveCode(fileId, id, codeRef.current)
        alert("Code Saved");
    }

   const params = useParams();
   console.log(params)
    const {fileId, id   } = params;  
    return(
        <div className="main-container">
            <div className="title-container">
                <div className="brand-container">
                <img src={ codelogo }></img>
                </div>
                <div className="button-container">
                <span class="material-symbols-outlined" onClick={onSaveCode}>save</span>
                <span class="material-symbols-outlined" onClick={homepage}>arrow_back</span>
                <div className="purple-stuff"><br></br></div>
                </div>
            </div>

            <div className="code-container">
                <EditorContainer />
            </div>
        </div>
    );
}

and here I have editorcontainer.js

import { useRef, useState } from "react";
import "./EditorContainer.scss"
import Editor from "@monaco-editor/react";
import { PlaygroundContext } from "../../Providers/PlaygroundProvider";

export const EditorContainer = (fileId, id) =>{

    const [code, setCode] = useState('');
    const codeRef = useRef();

    const editorOptions={
        theme: 'vs-dark',
        wordWrap: 'on' 
        }

    const onChangeCode = (newCode) =>{
        console.log(newCode);
        // setCode(newCode);
        codeRef.current = newCode;
    }

    return(
        <div className="root-editor-container">
                {/* <h1>YAHOOO</h1> */}
                <Editor 
                height={"100%"}
                language={"javascript"}
                options={editorOptions}
                theme={'vs-dark'}  
                onChange={onChangeCode}
                />
        </div>
    )
}

also the error is src\Screens\PlaygroundScreen\index.js Line 20:30: 'codeRef' is not defined

I tried to send it through the () in the export function but it brought another error of it not able to read .current


Solution

  • You have several errors in the code. First, if you need to use codeRef on PlaygroundScreen you should declare it there, then you need to pass it as a prop to EditorContainer.

    Second, your EditorContainer component is receiving props wrong as it should be an object or props destructured with the values you're passing on the parent component.

    Third, you are using the refs wrong. The references are used to avoid triggering on the components Lifecycle so, if you need to update the reference, you should pass it as a prop to Editor using the ref prop. After that, you can use the ref.current.value to access the value inside (Maybe it could be another key other than value, you can console.log it to be sure) without having to use the onChangeCode function. It will be something like this:

    import { useNavigate, useParams } from "react-router-dom";
    import "./playground.scss";
    import codelogo from "./vlogo.png";
    import { PlaygroundContext } from "../../Providers/PlaygroundProvider";
    import { Navigate } from "react-router-dom";
    import { EditorContainer } from "./EditorContainer";
    import { useContext } from "react";
    
    export const PlaygroundScreen = () =>{
        // here you declare the ref
        const codeRef = useRef();
        const {saveCode} = useContext(PlaygroundContext);
    
        const Navigate = useNavigate();
    
        const homepage = () => {
            Navigate(`/`);
        }
    
        const onSaveCode = () => {
            // now here you can use the codeRef.current
            saveCode(fileId, id, codeRef.current.value)
            alert("Code Saved");
        }
    
       const params = useParams();
       console.log(params)
        const {fileId, id   } = params;  
        return(
            <div className="main-container">
                <div className="title-container">
                    <div className="brand-container">
                    <img src={ codelogo }></img>
                    </div>
                    <div className="button-container">
                    <span class="material-symbols-outlined" onClick={onSaveCode}>save</span>
                    <span class="material-symbols-outlined" onClick={homepage}>arrow_back</span>
                    <div className="purple-stuff"><br></br></div>
                    </div>
                </div>
    
                <div className="code-container">
                    <EditorContainer codeRef={codeRef} />
                </div>
            </div>
        );
    }
    

    and the EditorContainer will be like:

    import { useRef, useState } from "react";
    import "./EditorContainer.scss"
    import Editor from "@monaco-editor/react";
    import { PlaygroundContext } from "../../Providers/PlaygroundProvider";
    
    
    /* As a plus, keep the statics variable declaration of your component to avoid the recreation on every re-rendering or having to memoize it. */
        const editorOptions={
            theme: 'vs-dark',
            wordWrap: 'on' 
            }
    
    /* here was receiving some data that wasn't passed through props so I deleted it */
    export const EditorContainer = ({codeRef}) =>{
    
        return(
            <div className="root-editor-container">
                    {/* <h1>YAHOOO</h1> */}
                    <Editor 
                    ref={codeRef}
                    height={"100%"}
                    language={"javascript"}
                    options={editorOptions}
                    theme={'vs-dark'}  
                    />
            </div>
        )
    }
    

    Hope this helps!