0

我正在尝试使用 react-intersection-observer 更改滚动时的背景视频。当 inView 更改为 true 时,useEffect 必须将 state 更改为 sample2,并将新视频发送到 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>
)};
4

1 回答 1

2

当您更改视频的来源时,该<video/>元素不会重新加载,如本答案所述:https ://stackoverflow.com/a/47382850 。

一种解决方法是

  return (
      <video key={sample} className="videoTag" autoPlay loop muted>
        <source src={sample} type="video/mp4" />
      </video>
  );

关于您的应用程序实施的一些注意事项

您根本不需要,因为您的组件会在更改useEffect时重新渲染。inView因此,您实际上根本不需要状态,因为您可以从inView. 试试这个:

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);,您实际上是在调用您之前的状态值,而不是您刚刚设置的状态值。

确实,如果您的状态是sample1,调用setState(sample2);then console.log(state);将打印sample1。将在由 this 引起的下一次重新渲染之后state相等,但您不会登录每个渲染,只有在更改时才会登录。您还可以通过添加到依赖数组来设法在重新渲染中记录新状态:sample2setStateinViewstateuseEffect

useEffect(() => {
    if (inView === true) {
      setState(sample2);
    } else {
      setState(sample1);
    }
    console.log(state);
  }, [inView, state]);
于 2021-06-12T17:05:31.987 回答