Как изменить фоновое видео при прокрутке в React?
Я пытаюсь изменить фоновое видео при прокрутке, используя наблюдатель-пересечение. Когда inView изменяется на true, useEffect должен изменить состояние на sample2 и отправить новое видео на стартовый экран, где оно будет использоваться в качестве фонового видео с фиксированной позицией. Состояние меняется, но видео остается прежним.
//Стартовый экран
const Startscreen = ({ sample }) => {
console.log(sample);
return (
<video className="videoTag" autoPlay loop muted>
<source src={sample} type="video/mp4" />
</video>
);
};
//App.js
import sample1 from "./videos/0.mov";
import sample2 from "./videos/2.mov";
function App() {
const [state, setState] = useState(sample1);
const { ref, inView, entry } = useInView({
threshold: 0.5,
});
useEffect(() => {
if (inView === true) {
setState(sample2);
} else {
setState(sample1);
}
console.log(state);
}, [inView]);
return (
<div className="App">
<Startscreen sample={state} />
<div ref={ref}>
<AboutMe>
</div>
</div>
)};
1 ответ
Когда вы меняете источник видео,
<video/>
элемент не перезагружается, как описано в этом ответе: /questions/11798299/obnovlenie-ishodnogo-url-v-video-html5-s-pomoschyu-react/11798314#11798314.
Одно исправление было бы
return (
<video key={sample} className="videoTag" autoPlay loop muted>
<source src={sample} type="video/mp4" />
</video>
);
Некоторые примечания по реализации вашего приложения
Вам вообще не нужно, так как ваш компонент будет повторно отрисовываться при изменении. Таким образом, вам вообще не нужно состояние, потому что вы можете вычислить свой образец из. Попробуйте вместо этого:
function App() {
const { ref, inView, entry } = useInView({
threshold: 0.5,
});
const sample = inView ? sample2 : sample1;
console.log(sample);
return (
<div className="App">
<Startscreen sample={sample} />
<div ref={ref}>
<AboutMe>
</div>
</div>
)};
Также обратите внимание, что в исходном коде, когда вы звоните
console.log(state);
, вы фактически вызываете свое предыдущее значение состояния, а не только что установленное значение состояния.
В самом деле, если ваше состояние, звоните
setState(sample2);
тогда
console.log(state);
напечатает
sample1
. будет равно
sample2
после следующего повторного рендеринга, вызванного этим
setState
, но вы не входите в каждый рендер, только когда
inView
изменения. Вы также можете зарегистрировать новое состояние при повторном рендеринге, добавив
state
к
useEffect
массив зависимостей:
useEffect(() => {
if (inView === true) {
setState(sample2);
} else {
setState(sample1);
}
console.log(state);
}, [inView, state]);