I am trying to change background video on scroll, using react-intersection-observer. When inView changes to true, useEffect must change state to sample2, and send new video to startscreen, where it's using as background video with position fixed. State is changing, but video is still the same.
//Startscreen
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>
)};
When you change the source of a video, the
<video/>
element doesn't reload, as explained in this answer : https://stackoverflow.com/a/47382850.One fix would be
Some notes on your App implementation
You don't need the
useEffect
at all since your component will re-render wheninView
changes. So you don't actually need a state at all because you can compute your sample frominView
. Try this instead:Also please note that in your original code, when you are calling
console.log(state);
, you are actually calling your previous state value, not the state value that you have just set.Indeed, if your state is
sample1
, callingsetState(sample2);
thenconsole.log(state);
will printsample1
.state
will equalsample2
after the next re-render caused by thissetState
, but you are not logging on each render, only wheninView
changes. You can manage to also log the new state in the re-rendering by addingstate
touseEffect
dependency array: