我无法理解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.netDevelopmentMotionRevealSlideshow。
然后,我试图应用CircleType JS库来对我的头文字进行弧形处理(顶部和底部,但我现在只用顶部来测试)。https:/circletype.labwire.ca。
然而,当我尝试这样做时,即使文本是显而易见的,标题的innerText也返回一个空值。因此,在我创建一个新的CircleType实例后,文本就消失了,我甚至无法检查它是否正确弯曲。
我尝试了一些东西来解决这个问题,但没有运气。我发现的关键问题是,1. innerText
内的顶部标题。useEffect
是空的,但当我 console.log(innerHTML)
2.既然(1)是真的,那么我就继续做了。innerText
内的页眉。useEffect
相当于 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 注明
如果你想只运行一次效果并清理它(在挂载和卸载时),你可以传递一个空数组(
[]
)作为第二个参数。这告诉React,你的效果不依赖于道具或状态的任何值,所以它永远不需要重新运行。这并不是作为一种特殊情况来处理的--它直接从依赖关系数组的工作方式中产生。如果您传递一个空数组(
[]
),效果中的道具和状态将始终保持其初始值。而传递 [] 作为第二个参数则更接近于我们熟悉的componentDidMount
和componentWillUnmount
心理模型,通常有更好的解决方案来避免过于频繁地重新运行效果。另外,别忘了,React会将运行useEffect的时间推迟到浏览器画好之后,所以做额外的工作就不那么麻烦了。