最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Getting "TypeError: Cannot read property 'classList' of null" on my React project

programmeradmin1浏览0评论

I am trying to implement useEffect on my React project to add my external JS file in.

This is my React code currently, with the mented out list being what I am trying to access from my script:

import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import './HeroSec.css';
import '../script.js';

function HeroSec(){

    useEffect(() => {
        console.log('render');

        const script = document.createElement('script');

        script.src = "../script.js";
        script.async = true;
      
        document.body.appendChild(script);
      
        return () => {
          document.body.removeChild(script);
        }
    })

    return(
    <div className='hero-container'>

        <h1>Example Name </h1> 
        {/*
        <ul id="foo" class="hidden-text">
        <li> E </li>
        <li class="hidden">x</li>
        <li class="hidden">a</li>
        <li class="hidden">m</li>
        <li class="hidden">p</li>
        <li class="hidden">l</li>
        <li class="hidden">e</li>
        <li class="spaced">N</li>
        <li class="hidden">a</li>
        <li class="hidden">m</li>
        <li class="hidden">e</li>
        </ul>
        */}

and this is the script.js file I am getting the error in.

const text = document.querySelector("#foo");
    setTimeout(() => {
        text.classList.toggle("hidden-text");
    }, 1000);

Essentially, I am just trying to grab that list element in React, and use the script to set a timeout so I can toggle off the hidden-text class. Of course there is some CSS that does this separately.

Hopefully I made it easy to understand the bigger picture of what I am trying to do and any help on that would be appreciated. In terms of the specific TypeError I am getting, is there maybe another property instead of classList that I can use to access the list from within React?

I am trying to implement useEffect on my React project to add my external JS file in.

This is my React code currently, with the mented out list being what I am trying to access from my script:

import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import './HeroSec.css';
import '../script.js';

function HeroSec(){

    useEffect(() => {
        console.log('render');

        const script = document.createElement('script');

        script.src = "../script.js";
        script.async = true;
      
        document.body.appendChild(script);
      
        return () => {
          document.body.removeChild(script);
        }
    })

    return(
    <div className='hero-container'>

        <h1>Example Name </h1> 
        {/*
        <ul id="foo" class="hidden-text">
        <li> E </li>
        <li class="hidden">x</li>
        <li class="hidden">a</li>
        <li class="hidden">m</li>
        <li class="hidden">p</li>
        <li class="hidden">l</li>
        <li class="hidden">e</li>
        <li class="spaced">N</li>
        <li class="hidden">a</li>
        <li class="hidden">m</li>
        <li class="hidden">e</li>
        </ul>
        */}

and this is the script.js file I am getting the error in.

const text = document.querySelector("#foo");
    setTimeout(() => {
        text.classList.toggle("hidden-text");
    }, 1000);

Essentially, I am just trying to grab that list element in React, and use the script to set a timeout so I can toggle off the hidden-text class. Of course there is some CSS that does this separately.

Hopefully I made it easy to understand the bigger picture of what I am trying to do and any help on that would be appreciated. In terms of the specific TypeError I am getting, is there maybe another property instead of classList that I can use to access the list from within React?

Share Improve this question edited Oct 14, 2022 at 6:53 starball 53.9k34 gold badges235 silver badges927 bronze badges asked Mar 12, 2021 at 19:21 dom-noochdom-nooch 211 gold badge2 silver badges5 bronze badges 5
  • Are the ment markers around your element with id "foo" really there? – ASDFGerte Commented Mar 12, 2021 at 19:23
  • Yes. Idk why stackoverflow shows them unmented. But yes, on my end they are mented simply because I wanted to ment them out until I figured out the problem here. – dom-nooch Commented Mar 12, 2021 at 19:27
  • So you mented out the element with id "foo", then search for your element with id "foo", don't find it, and then be confused? – ASDFGerte Commented Mar 12, 2021 at 19:28
  • LOL, no sir. The error I was getting was without the mented element "foo". Like I said, I just put the ments there now until I figured out what was wrong. I cannot tell if you are trying to be helpful or rude? – dom-nooch Commented Mar 12, 2021 at 19:31
  • That's fine then, i've just seen some things on this site, so i better make sure. You seem to import '../script.js'; as well, but also inject it into DOM as a script element, why the doubling? The import part is probably done immediately, so const text = document.querySelector("#foo"); in there would execute before react had any time to render. – ASDFGerte Commented Mar 12, 2021 at 19:37
Add a ment  | 

2 Answers 2

Reset to default 3

Ideally you use the useRef hook to access element with React function ponents. For example:

export default function HeroSec() {
  const listElement = useRef(null);

  useEffect(() => {
    setTimeout(() => {
      listElement.current.classList.add("hidden-text");
    }, 1000);
    return () => {};
  });

  return (
    <div className="hero-container">
      <h1>Example Name </h1>
      <ul ref={listElement} id="foo">
        <li> E </li>
        <li className="hidden">x</li>
        <li className="hidden">a</li>
      </ul>
    </div>
  );
}

Sandbox: https://codesandbox.io/s/frosty-cache-6rkdq?file=/src/App.js

This is not the "react" way of doing things, you should not be getting direct references to html elements and modifying them in React. I did not quite understand what you want to do but you can try below approach to render ponents differently according to the state.

function HeroSec(){
  const [toggled,setToggled] = useState(false);
  ...

 return ( ....
 //Component will have different class based on the value of toggled and
 // when toggled value changed react will re-render the element with new value
 <ul id="foo" class={toggled ? : "hidden-text" : <another_classname>} >
  ...)

Then use setToggled in your setTimeout function to change toggled from false to true.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论