UseEffect React Hook 中的空 innerText

Empty innerText in UseEffect React Hook

我无法理解 useEffect 的工作原理。 我在下面有一段代码:

import React, { useState, useEffect, useLayoutEffect, useRef, createRef } from "react";
import {Link} from "react-router-dom";
import LoadingPage from "../LoadingPage";
import Slideshow from "../SlideShow"
import CircleType from "circletype";

function Home() {
  const categories = ["advance beauty", "beauty", "special effects", "airbrush", "others"]
  const images = useState(
    [[
      "/images/elegant_sugar_skull4.jpg",
      "/images/elegant_sugar_skull3.jpg",
      "/images/elegant_sugar_skull1.jpg"
    ],
    [
      "/images/3looks1.jpg",
      "/images/3looks4.jpg",
      "/images/3looks5.jpg"
    ],
    [
      "/images/daemon_of_buddha1.jpg",
      "/images/daemon_of_buddha6.jpg",
      "/images/daemon_of_buddha7.jpg"
    ],
    [
      "/images/gangstar4.jpg",
      "/images/gangstar2.jpg",
      "/images/gangstar6.jpg"
    ],
    [
      "/images/sculpture1.jpg",
      "/images/sculpture6.jpg",
      "/images/henna1.jpg"
    ]]);

useEffect(() => {
        const slideshow = new Slideshow(document.querySelector('.slideshow'));
        const topText = document.querySelectorAll('.bottom');
        console.log(topText[0].innerText);
        topText.forEach(text=>{
          console.log(text.innerText)
          new CircleType(text).radius(384)
        })
  }, []); 

return (
<div className="slideshow">
        {categories.map((category, index) => (
            <div className="slide" key={index}>
            <div className="slide__number white-text">0{index + 1}</div>
              <div className="slide__img-wrap">
                <img className="slide__img" src={images[0][index][0]} onLoad={checkLoaded} alt="img" />
                <img className="slide__img2" src={images[0][index][1]} onLoad={checkLoaded} alt="img" />
                <img className="slide__img3"  src={images[0][index][2]} onLoad={checkLoaded} alt="img" />
                <div className="slide__img-reveal"></div>
              </div>
              {category.includes(" ") ?
              <div className="slide__title">
                <h1 className="white-text top">{category.split(" ")[0]}</h1>
                <h1 className="white-text bottom" ref={bottomText}>{category.split(" ")[1]}</h1>
                </div>
                :
                <div className="slide__title">
              <h1 className="white-text bottom" ref={bottomText}>{category}</h1>
              </div>
              }          
              </div>))      
        }
        <div className="total-images white-text">05</div>
      </div> 
)

我基本上是为每个类别绘制幻灯片(3 张图片,每张幻灯片 1 个标题)。我在下面使用外部 WebGL 库(根据我的需要进行了修改): https://tympanus.net/Development/MotionRevealSlideshow/

然后,我尝试应用 CircleType JS 库来生成我的 header 文本(顶部和底部,但我只是用顶部的 atm 来测试一下): https://circletype.labwire.ca/

但是,当我尝试这样做时,headers return 的 innerText 是一个空值,即使文本是显而易见的。所以在我创建一个新的 CircleType 实例后,文本就消失了,我无法检查它是否正确弯曲。

我尝试了一些方法来解决这个问题,但没有成功。我发现的关键是, 1. useEffect里面最上面header的innerText是空的,但是当我console.log(innerHTML)里面的文字是有的。 2. 由于 (1) 为真,我继续将 useEffect 内的 header 的 innerText 设为 innerHTML,但是当 DOM 完全呈现文本只是成为该特定文本的完整 div 标记。无论如何,文本不是弯曲的。

我以为空括号的useEffect === componentDidMount,但如果是这样我就不知道为什么会这样了。

如果有人能就此事给我一些提示或见解,我将不胜感激。

感谢您的宝贵时间。

我怀疑 useEffect 中的第二个参数 [] 是麻烦制造者。它导致 useEffect 使用默认道具和统计信息仅被调用一次。尝试删除它:

useEffect(() => {
        const slideshow = new Slideshow(document.querySelector('.slideshow'));
        const topText = document.querySelectorAll('.bottom');
        console.log(topText[0].innerText);
        topText.forEach(text=>{
          console.log(text.innerText)
          new CircleType(text).radius(384)
        })
  }); 

React docs 在注释中说明

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

If you pass an empty array ([]), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.