我是 ReactJS 和轮播的初学者。我想编写一个看起来像这样的旋转木马,自动旋转:
我想我了解轮播的一般做法:
data
数组;data
(data.map((obj, index) => (...))
)的每个元素映射到一个HTML元素;slideInd
,它将表示数组第 0 个元素的 margin-left
CSS 属性的值 data
;useEffect
钩子触发更新第 0 个数组元素的 margin-left
CSS 属性的状态,创建向左滑动的效果(尽管它只是修改第 0 个元素的状态);useEffect
setTimeout()
函数中,如果你的状态已经达到data
数组的长度,确保循环回到第0个元素;例如,
import { v4 as uuidv4 } from "uuid";
import styled from "@emotion/styled"
import { useState, useEffect } from "react";
const Wrapper = styled.div`
display: flex;
overflow-x: visible;
`;
const Slide = styled.div`
width: 100%;
flex-shrink: 0;
outline: 3px solid green;
transition: all 1s ease-in-out;
display: flex;
justify-content: center;
align-items: center;
&::before{
content: "";
min-height: 100px;
}
`
const data = [
{'id': uuidv4(), 'title': 'slide1'},
{'id': uuidv4(), 'title': 'slide2'},
{'id': uuidv4(), 'title': 'slide3'},
]
const Test = ({ ...props }) => {
const [slideInd, setSlideInd] = useState(0)
useEffect(() => {
const timeout = setTimeout(() => {
// If at the end, scroll all the way back to the beginning
// ideal function: go back one step at a time instead
const n = slideInd >= data.length - 1 ? 0 : slideInd + 1
setSlideInd(n)
console.log(`Rotate margin left 0th element by: -${slideInd*100}%`)
// Here, "2000" is the delay miliseconds that the timer waits
// before the "timeout" function is executed -- this is the
// miliseconds before each slide "slides"
}, 2000)
// Clear the timeout to avoid any memory leaks
return () => clearTimeout(timeout)
}, [slideInd])
return (
<Wrapper {...props}>
{data.map((obj, index) => (
<Slide
style={{
marginLeft: index === 0 ? `-${slideInd * 100}%` : undefined,
}}
// Each child in a list should have a unique "key" prop
key={obj.id}
>
{obj.title}
</Slide>
))}
</Wrapper>
)
}
export default Test
如果我尝试改变它来实现我的想法,我想:
margin-left
的索引,而是改变data
数组的状态本身useEffect
中,通过将第一个元素放到最后一个位置来更新data
import { v4 as uuidv4 } from "uuid";
import styled from "@emotion/styled"
import { useState, useEffect } from "react";
const Wrapper = styled.div`
display: flex;
overflow-x: visible;
justify-content: center;
align-items: center;
`;
const Slide = styled.div`
flex-shrink: 0;
outline: 3px solid green;
transition: all 1s ease-in-out;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 520px;
background: rgba(255, 255, 255, 0.7);
&::before{
content: "";
min-height: 330px;
}
`
const Test = ({ ...props }) => {
const [data, setData] = useState([
{'id': uuidv4(), 'title': 'slide1', 'p': 1},
{'id': uuidv4(), 'title': 'slide2', 'p': 3},
{'id': uuidv4(), 'title': 'slide3', 'p': 5},
])
useEffect(() => {
const timeout = setTimeout(() => {
// Push first element to end of array
let el = data.shift()
data[data.length] = el
setData([...data])
}, 3600)
// Clear the timeout to avoid any memory leaks
return () => clearTimeout(timeout)
}, [data])
return (
<Wrapper {...props}>
{data.map((obj, index) => (
<Slide
style={{
marginLeft: `${index}%`,
marginTop: `-${index}%`,
zIndex: -index,
}}
// Each child in a list should have a unique "key" prop
key={obj.id}
>
{obj.title}
</Slide>
))}
</Wrapper>
)
}
export default Test
这确实不断地旋转数组的元素,但它缺少:
有没有办法在不必更新
data
数组本身的值的情况下实现这种混洗效果?
谢谢!!