Как я могу использовать setInterval () для автоматического изменения слайдов в этом проекте React Spring - PullRequest
1 голос
/ 22 января 2020

Я реализовал этот компонент React Spring, который получает другой слайд после нажатия на него. Я хотел бы, чтобы он менялся автоматически каждые X секунд с помощью метода setInterval.

Я пытался использовать 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={() => { setInterval(onClick, 3000) }}

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Вы звоните setInterval на каждом рендере, поэтому каждый раз создается новый интервал, а ваш первый все еще работает. Так что вы просто добавляете все больше и больше, пока он не перегружает браузер.

Так как вы хотите, чтобы интервал начинался до того, как что-то щелкнуло, добавьте его к эффекту, чтобы вы могли запускать его, когда приложение монтирует и очищает его unmount.

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

Затем просто удалите setInterval в onClick, и вы должны быть хороши до go.

0 голосов
/ 22 января 2020

Вы можете использовать useeffect для создания того же эффекта, что и жизненный цикл "componentdidmount". во-первых, вы не можете вызвать setinterval напрямую, потому что он будет вызывать рендеринг, поэтому вам нужно обернуть его в анонимную функцию, во-вторых, даже если вы используете его таким образом, ваш щелчок изменяет состояние и это также вызывает рендеринг каждый раз, даже не завершив первый и продолжая делать это, ваш браузер будет зависать из-за большого количества созданных им интервалов, поэтому лучший способ - очистить ваш setinterval при размонтировании, чтобы каждый рендер имел только один интервал для работы.

...