【问题标题】:Getting "TypeError: Cannot read property 'classList' of null" on my React project with useEffect when trying to access a script?尝试访问脚本时使用useEffect在我的React项目上获取“TypeError:无法读取null的属性'classList'”?
【发布时间】:2021-03-12 19:21:11
【问题描述】:

我正在尝试在我的 React 项目上实现 useEffect 以添加我的外部 JS 文件。

这是我目前的 React 代码,注释掉的列表是我试图从我的脚本中访问的内容。

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>
        */}

这是我遇到错误的 script.js 文件。

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

基本上,我只是想在 React 中获取该列表元素,并使用脚本设置超时,以便我可以关闭隐藏文本类。当然,有一些 CSS 会单独执行此操作。

希望我能够轻松理解我正在尝试做的事情的大局,并且对此提供任何帮助将不胜感激。就我得到的特定 TypeError 而言,是否有另一个属性而不是 classList 可以用来从 React 中访问列表?

【问题讨论】:

  • 你的元素周围的评论标记真的存在吗?
  • 是的。 Idk 为什么 stackoverflow 显示它们未注释。但是,是的,就我而言,它们被评论只是因为我想将它们评论出来,直到我发现这里的问题。
  • 所以你注释掉了id为“foo”的元素,然后搜索你的id为“foo”的元素,没找到,然后一头雾水?
  • 大声笑,不,先生。我得到的错误是没有注释元素“foo”。就像我说的那样,我现在只是把 cmets 放在那里,直到我弄清楚出了什么问题。我不知道你是想乐于助人还是粗鲁?
  • 那很好,我刚刚在这个网站上看到了一些东西,所以我最好确定一下。你好像import '../script.js';也是这样,还把它作为脚本元素注入到DOM中,为什么要加倍呢? import 部分可能会立即完成,因此其中的 const text = document.querySelector("#foo"); 会在 react 有时间渲染之前执行。

标签: javascript reactjs use-effect script


【解决方案1】:

理想情况下,您使用 useRef 挂钩来访问具有 React 功能组件的元素。例如:

  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>
  );
}

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

【讨论】:

  • 感激不尽。我对 React 还很陌生,这很完美。昨天我试图学习 useRef,在我开始尝试 useEffect 之前,我的解决方案已经完成了大约一半。我几乎不知道我实际上需要两者,所以非常感谢你。
【解决方案2】:

这不是“react”的做事方式,你不应该直接引用 html 元素并在 React 中修改它们。我不太明白您想要做什么,但您可以尝试以下方法根据状态以不同方式呈现组件。

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>} >
  ...)

然后在 setTimeout 函数中使用 setToggled 将 toggled 从 false 更改为 true。

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 2019-03-25
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 2021-01-19
    • 2021-11-07
    相关资源
    最近更新 更多