Home > Software engineering >  My innerHTML is coming out to be null despite using id or class or querySelector
My innerHTML is coming out to be null despite using id or class or querySelector

Time:10-23

This is the most frequent problem I come across, in this file was trying to access the innerHTML of the textarea using the same property.

But the error says that the input.innerHTML is null.

You can understand better by code,

import React, { Component, useEffect, useState } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
    let noteArray;
    let input =  document.getElementById('.input_area') ;
    const AddNote = () =>{
        console.log("here" ,input.innerHTML) ; 
    }
    return (
        <>
            <div>
                <div className="input_info">
                    <textarea id='input_area' name=""  cols="50" rows="5">op</textarea>
                    <br />
                    <button onClick={AddNote} className='add'>Add Note</button>
                </div>
                <br />
                <div id='display_info' >
                    
                </div>
            </div>
        </>
    )
}

I tried from class, id, and querySelector but none of them is working.

Can anyone suggest me some edits?

EDIT--

THIS IS THE CONSOLE

CodePudding user response:

To be sure that the elements of the component has been mounted to the DOM you need to execute the selection queries in useEffect hook, Also you need to use value attribute instead of innerHTML

import React, { Component, useEffect, useState } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
    let noteArray;
    useEffect(() => {
       let input =  document.getElementById('.input_area');
       console.log("here" ,input.value);
    })
    
    const AddNote = () =>{
       let input =  document.getElementById('.input_area');
       console.log("here" ,input.value); 
    }
    return (
        <>
            <div>
                <div className="input_info">
                    <textarea id='input_area' name=""  cols="50" rows="5">op</textarea>
                    <br />
                    <button onClick={AddNote} className='add'>Add Note</button>
                </div>
                <br />
                <div id='display_info' >
                    
                </div>
            </div>
        </>
    )
}

But, I suggest you use useRef instead of DOM select queries.

For example

import React, { Component, useEffect, useState, useRef } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
    let noteArray;
    const textAreaRef = useRef(null)
    useEffect(() => {
       console.log(textAreaRef.current.value)
    })
    
    const AddNote = () =>{
       console.log(textAreaRef.current.value)
    }
    return (
        <>
            <div>
                <div className="input_info">
                    <textarea ref={textAreaRef} id='input_area' name=""  cols="50" rows="5">op</textarea>
                    <br />
                    <button onClick={AddNote} className='add'>Add Note</button>
                </div>
                <br />
                <div id='display_info' >
                    
                </div>
            </div>
        </>
    )
}

CodePudding user response:

const { useState } = React;

function Navbar() {
    const [input, setInput] = useState("op");
    const [noteArray, setNoteArray] = useState([])
    const addNote = () => {
        setNoteArray((prevState) => ([...prevState, input]))
    }

    const inputChange = (e) => {
        setInput(e.target.value)
    }
    return (
        <div>
            <div className="input_info">
                <textarea id='input_area' name="" cols="50" rows="5" value={input} onChange={e => inputChange(e)}></textarea>
                <br />
                <button className='add' onClick={addNote}>Add Note</button>
            </div>
            <br />
            <div id='display_info' >
                <ul>
                    {noteArray.map(val => {
                        return <li>{val}</li>
                    })
                    }
                </ul>
            </div>
        </div>
    );
}
ReactDOM.render(<Navbar />, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

<body id="root"></body>

I guess this is what you want to achieve and a better pattern in react. Also you can improve it by changing the data structure of note array

  • Related