【问题标题】:How can I use setInterval() to automatically change slides on this React Spring project如何使用 setInterval() 自动更改此 React Spring 项目的幻灯片
【发布时间】:2020-05-08 22:13:30
【问题描述】:

我实现了这个 React Spring 组件,点击它后会得到一张不同的幻灯片。我想通过使用setInterval 方法使其每隔 X 秒自动更改一次。

我尝试使用 setInterval,但没有得到想要的结果,因为 setInterval 函数被多次调用,随着时间的增加,幻灯片开始疯狂地变化,直到浏览器冻结。

这里是codeandbox原始项目https://codesandbox.io/embed/1y3yyqpq7q

这是我目前正在运行的代码

import { useTransition, animated } from 'react-spring'
import clientStyles from '../../styles/modules_scss/clients.module.scss'

const pages = [
    ({ style }) => <animated.div style={{ ...style, background: 'lightpink' }}>Andres Mejias</animated.div>,
    ({ style }) => <animated.div style={{ ...style, background: 'lightblue' }}>Andres Urdaneta</animated.div>,
    ({ style }) => <animated.div style={{ ...style, background: 'lightgreen' }}>Gustavo Abdelnour</animated.div>,
]

export default function SlideTransition() {
    const [index, set] = useState(0)
    const onClick = useCallback(() => set(state => (state + 1) % 3), [])
    const transitions = useTransition(index, p => p, {
        from: { opacity: 0, transform: 'translate3d(100%,0,0)' },
        enter: { opacity: 1, transform: 'translate3d(0%,0,0)' },
        leave: { opacity: 0, transform: 'translate3d(-50%,0,0)' },
    })
    return (
        <div className={clientStyles.simpleTransMain} onClick={setInterval(onClick, 3000)}> //Here's my approach
            {transitions.map(({ item, props, key }) => {
                const Page = pages[item]
                return <Page key={key} style={props} />
            })}
        </div>
    )
}

我得到的最好结果是将setInterval 包装在一个匿名函数中,然后单击第一张幻灯片后,我每3000ms 都会得到一张新幻灯片。我希望在页面加载后无需单击幻灯片就可以做到这一点。

onClick={() =&gt; { setInterval(onClick, 3000) }}

【问题讨论】:

    标签: javascript reactjs settimeout setinterval react-spring


    【解决方案1】:

    您在每次渲染时都调用setInterval,因此每次都会创建一个新间隔并且您的第一个间隔仍在运行。所以你只会得到越来越多的添加,直到它使浏览器过载。

    由于您希望间隔在单击任何内容之前开始,请将其添加到效果中,以便您可以在应用挂载时运行它并在卸载时清除它。

    useEffect(() => {
      const interval_id = setInterval(onClick, 3000);
       return () => {
         // Stop the interval when the component unmounts. 
         // Otherwise it will keeep going and you will get an error.
         clearInterval(interval_id)
       }
    }, []); // empty array of dependencies will cause it to run on mount and unmount only
    

    然后只需删除onClick 中的setInterval 就可以了。

    【讨论】:

      【解决方案2】:

      你可以使用 useEffect 来做出与生命周期“componentdidmount”相同的效果。 首先,你不能直接调用 setinterval 因为它会一直导致渲染,这就是为什么你需要将它包装在一个匿名函数中,其次,即使你这样使用它,你的 onclick 正在改变状态,这也会导致渲染每次甚至没有完成第一个,并且继续这样做会导致您的浏览器因为它创建的大量间隔而冻结,所以最好的方法是在卸载时清除您的 setinterval,这样每次渲染只会有一个工作间隔。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多