访问react中动态创建的一组元素



我已经用纯JS实现了这一点,我正试图通过将其翻译成React来在Gatsby网站上实现同样的东西。基本上,重点是让字母以随机的顺序出现,但要放在正确的位置。

我陷入困境的地方(我对React很陌生(是如何以随机顺序创建和访问元素集(跨度(,以便能够使它们按该顺序显示。

class about extends Component {
constructor(props) {
super(props);
this.state = {
aboutText: "This is a test of the emergency broadcast system",
aboutElements: []
}
}

shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
render() {
const arrLetters = this.state.aboutText.split("");
let arrNumbers = Array.from(Array(arrLetters.length).keys());
arrNumbers = this.shuffleArray(arrNumbers);
const arrSpans = arrLetters.map((letter, index) => <span key={index} id={"letter" + index}>{letter}</span>);
console.log(arrSpans)
this.setState({ aboutElements: arrSpans })
arrNumbers.forEach(function(item, index) {
let targetSpan = arrSpans.filter( el => el.key == item);
// NEED TO MAKE THE LETTER VISIBLE HERE

});

return (
<section id="about" className={styles.about}>
<div className="container">
<p>{ this.state.aboutElements }</p>
</div>
</section>
)
}

}
export default about

所以我创建的字母数组,把它变成一个元素数组,但当我试图把它放进一个状态时,我得到了这个错误:

超过了最大更新深度。当组件在componentWillUpdatecomponentDidUpdate内重复调用setState时,可能会发生这种情况。React限制了嵌套更新的数量,以防止无限循环。

我做错了什么?

问题是在render方法内部调用this.setState({ aboutElements: arrSpans })。每次状态发生变化时都会调用render函数,因此蛇会在这里咬尾巴,从而创建一个无休止的render循环->setState->渲染->设置状态->。。

但好消息是,您可以只使用局部变量来渲染元素,而不使用状态:

render() {
const arrLetters = this.state.aboutText.split("");
const arrSpans = arrLetters.map((letter, index) => <span key={index} id={"letter" + index}>{letter}</span>);
console.log(arrSpans)
// this.setState({ aboutElements: arrSpans }) // <- not needed

return (
<section id="about" className={styles.about}>
<div className="container">
<p>{ arrSpans }</p>
</div>
</section>
)
}

我不确定你对arrNumbers的计划是什么,但我想你可以自己解决这个问题,因为你知道你可以只使用局部变量

更新:

我只是在这里快速地画了一个想要的效果。

这是代码的副本:

import React, { useEffect, useState, useRef } from "react";
export default function AnimatedLetters({ text }) {
const interval = useRef();
const [elements, setElements] = useState([]);
useEffect(() => {
let count = 0;
if (interval.current) {
clearInterval(interval.current);
}
const indices = shuffleArray(
Array.from({ length: text.length }, (_, i) => i)
);
interval.current = setInterval(() => {
++count;
const chars = text.split("").map((char, i) => (
<span key={i} style={{ opacity: indices[i] < count ? 1 : 0 }}>
{char}
</span>
));
setElements(chars);
if (count > text.length) {
clearInterval(interval.current);
}
}, 100);
}, [text]);
return <p>{elements}</p>;
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}

示例用法:

export default function App() {
const [text, setText] = useState("Hello Codesandbox");
return (
<div className="App">
<AnimatedLetters text={text} />
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
</div>
);
}

更新:现在可以动态更改文本

最新更新