首页 > 解决方案 > UseEffect React Hook 中的空 innerText

问题描述

我无法理解 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 库来绘制我的标题文本(顶部和底部,但我只是使用顶部 atm 进行测试): https ://circletype.labwire.ca/

但是,当我尝试这样做时,即使文本很明显,标题的 innerText 也会返回一个空值。所以在我创建一个新的 CircleType 实例后,文本就消失了,我无法检查它是否正确弯曲。

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

我认为useEffect空括号 === componentDidMount,但如果是这种情况,我不知道为什么会发生这种情况。

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

感谢您的时间。

标签: javascriptreactjsreact-hooksuse-effectcircletype

解决方案


我怀疑[]第二个论点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 文档在注释中指出

如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组 ( []) 作为第二个参数。这告诉 React 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。这不是作为特殊情况处理的——它直接遵循依赖项数组的工作方式。

如果您传递一个空数组 ( []),则效果内的 props 和 state 将始终具有它们的初始值。虽然将 [] 作为第二个参数传递更接近于熟悉的componentDidMount心理componentWillUnmount模型,但通常有更好的解决方案来避免过于频繁地重新运行效果。另外,不要忘记 React 会延迟运行 useEffect 直到浏览器绘制完成,所以做额外的工作不是问题。


推荐阅读