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.
我无法理解 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 familiarcomponentDidMount
andcomponentWillUnmount
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.