[英]How to cycle className over children in React
I would like to use a setInterval
to cycle which <li>
object has a className
of "showing", like this simple slideshow . 我想使用
setInterval
循环哪个<li>
对象的className
为“ showing”,就像这个简单的slideshow一样 。 I don't know how to do this in React-land. 我不知道如何在React-land中做到这一点。
function NumberList() {
const numbers = [1, 2, 3, 4, 5];
return (
<ul>
{
numbers.map((number) =>
<li key={number.toString()}>{number}</li>
)
}
</ul>
);
}
ReactDOM.render(
<NumberList />,
document.getElementById('root')
);
Anybody have any ideas? 有人有什么想法吗?
Here's a working demo. 这是一个工作示例。 Basically, you need to start a timer and keep the current showing list item in the state.
基本上,您需要启动一个计时器并将当前的显示列表项保持在该状态。 The timer will increment the current number every 500ms and wrap around when it exceeds the number of items.
计时器将每500ms递增当前数字,并在超过项目数时回绕。
Some things to take note of: 需要注意的一些事情:
Use the alternative signature of this.setState
because setState
is not guaranteed to be synchronous and if you refer to this.state
within setState
it might be outdated. 使用
this.setState
的替代签名,因为不能保证setState
是同步的,并且如果在setState
引用this.state
,则它可能已过时。
Remember to clear the timer upon unmount of the component. 切记在卸下组件时清除计时器。
class App extends React.Component { constructor(props) { super(props); this.numbers = [1, 2, 3, 4, 5]; this.state = { current: 0, }; } componentDidMount() { this.timerId = setInterval(() => { this.setState(state => ({ ...state, current: (state.current + 1) % this.numbers.length, })); }, 500); } componentWillUnmount() { clearInterval(this.timerId); } render() { return ( <div className="App"> <ul> {this.numbers.map((number, index) => ( <li key={number} className={index === this.state.current ? 'slide showing' : 'slide'} > {number} </li> ))} </ul> </div> ); } } ReactDOM.render( <App />, document.getElementById('root') );
.slide { font-size: 40px; padding: 40px; box-sizing: border-box; background: #333; color: #fff; display: none; width: 100%; height: 40px; } .slide.showing { display: inherit; } .slide:nth-of-type(1){ background: red; } .slide:nth-of-type(2){ background: orange; } .slide:nth-of-type(3){ background: green; } .slide:nth-of-type(4){ background: blue; } .slide:nth-of-type(5){ background: purple; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"><div>
You will probably need to use componentDidMount
function to use the setInterval
function so you have access to the classes. 您可能需要使用
componentDidMount
函数才能使用setInterval
函数,以便可以访问这些类。 Also use ref
to get the hold of the element itself. 也可以使用
ref
来获取元素本身的所有权。
https://reactjs.org/docs/refs-and-the-dom.html#when-to-use-refs https://reactjs.org/docs/refs-and-the-dom.html#when-to-use-refs
Within the componentDidMount
get access to the element and then you should be able to any JS stuff. 在
componentDidMount
可以访问该元素,然后您应该可以使用任何JS东西。
demo: https://codesandbox.io/s/oopj96pv65 演示: https : //codesandbox.io/s/oopj96pv65
import React from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";
class App extends React.Component {
componentDidMount() {
var slides = this.elem.children;
var currentSlide = 0;
setInterval(() => {
slides[currentSlide].classList.remove("showing");
currentSlide = (currentSlide + 1) % slides.length;
slides[currentSlide].classList.add("showing");
}, 2000);
}
render() {
return (
<ul
id="slides"
ref={elem => {
this.elem = elem;
}}
>
<li className="slide showing">Slide 1</li>
<li className="slide">Slide 2</li>
<li className="slide">Slide 3</li>
<li className="slide">Slide 4</li>
<li className="slide">Slide 5</li>
</ul>
);
}
}
render(<App />, document.getElementById("root"));
Building on your simple example: 以您的简单示例为基础:
// Store the state outside of the components
const numbers = [1, 2, 3, 4, 5];
let activeNumber = 0;
// A stateless NumberList component takes the numbers and activeNumber props
function NumberList(props) {
// The `active` class is conditionally added to the appropriate `li`
return (
<ul>
{
props.numbers.map((number) =>
<li key={number} className={props.activeNumber === number ? 'active' : ''}>
{number}
</li>
)
}
</ul>
);
}
// Render method takes in the active number
function render(activeNumber) {
ReactDOM.render(
<NumberList numbers={numbers} activeNumber={activeNumber} />,
document.getElementById('root')
);
}
// We set an interval timer to update activeNumber and re-render
setInterval(function() {
if (activeNumber < numbers.length) {
activeNumber++
} else {
activeNumber = 1;
}
render(activeNumber);
}, 1000);
render(); // Initial render
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.