@StepsOnes

Почему из-за Suspense в React.js(ts) не срабатывает onLoadedData на видео?

Нашел очень странный баг с Suspense. В чем суть: использую библиотеку для перевода i18next, она просит использовать suspense для корректной работы, и у видео не срабатывает обработчик onLoadedData(срабатывает через раз), когда убираю Suspense все работает ок. Самое странное то, что на продакшн версии обработчик корректно работает. Использую TypeScript.

Мой index.js:
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
	<React.StrictMode>
		<I18nextProvider i18n={i18n}>
			<HelmetProvider>
				<Provider store={store}>
					<WagmiConfig config={client}>
						<Suspense fallback={<Preload />}>
							<App />
						</Suspense>
					</WagmiConfig>
				</Provider>
			</HelmetProvider>
		</I18nextProvider>
	</React.StrictMode>


Компонент с видео:
const AboutRooms = () => {
	const videoRef = useRef<HTMLVideoElement>(null)
	const [isLoading, setLoading] = useState<boolean>(true)
	const dispatch = useAppDispatch()
	const { t } = useTranslation('home')
	const API_KEY = process.env.REACT_APP_API_KEY

	const handleOnLoadedData = () => {
		setLoading(false)
		console.log('Video loaded')
	}

	return (
		<div className={styles.aboutRooms}>
			<div style={{ paddingTop: '75%' }} className={styles.videoWrapper}>
				<video
					onLoadedData={handleOnLoadedData}
					onError={() => {
						setLoading(false)
						console.log('Error loading video')
					}}
					className={styles.video}
					autoPlay
					muted
					playsInline
					loop
					crossOrigin='anonymous'
				>
					<source src={`${API_KEY}/static/videos/appart-build.mp4`} />
					<source src={`${API_KEY}/static/videos/appart-build.webm`} />
				</video>
			</div>

			{isLoading && (
				<div className={styles.loadVideoScreen}>
					<div>
						<CircularProgress color='inherit' />
					</div>
				</div>
			)}
		</div>
	)
}

export default AboutRooms
  • Вопрос задан
  • 206 просмотров
Пригласить эксперта
Ответы на вопрос 2
scoffs
@scoffs
Fullstack | C# | Student
Возможно, что видео не срабатывает или срабатывает не всегда, потому что оно еще не загружено на момент первого рендеринга компонента. Из-за этого обработчик может пропустить событие onLoadedData.

// может использовать onCanPlayThrough ? Или onCanPlay / onPlay
const handleOnCanPlayThrough = () => {
  setLoading(false)
  console.log('Video loaded')
}

<video
  onCanPlayThrough={handleOnCanPlayThrough}
  // ...
>
Ответ написан
Alexandroppolus
@Alexandroppolus
кодир
Самое странное то, что на продакшн версии обработчик корректно работает

почти наверняка из-за React.StrictMode - там двойное монтирование, и вообще всё двойное. Попробуй его убрать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы