1

我正在使用这样的 React Context并且真的陷入了如何更新我的视频元素(播放视频)。收到道具时组件不应该自动更新吗?

这是我的代码的简化版本:


import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Video } from "grommet";

import LanguageContext from "./language-context";
import LanguageSwitcher from "./LanguageSwitcher";

const App = () => {
  const [language, setLanguage] = useState("en");
  const value = { language, setLanguage };
  console.log(language); // shows language on click

  return (
    <LanguageContext.Provider value={value}>
      <h2>Current Language: {language}</h2>
      <p>Click button to change to jp</p>
      <div>
        {/* Can be nested */}
        <LanguageSwitcher />
          <VideoWrapper>
            <Video fit='cover' controls='over'>
                <source key='video' src="example.mp4" type='video/mp4' poster="example.jpg"/>
                   <track
                        srcLang={language}
                        src='//v2.grommet.io/assets/small-en.vtt'
                        default={true}
                    />
            </Video>
          </VideoWrapper>
      </div>
    </LanguageContext.Provider>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

和(在我的情况下非常嵌套的)子组件

import React, { useContext } from "react";

import LanguageContext from "./language-context";

const LanguageSwitcher = () => {
  const { language, setLanguage } = useContext(LanguageContext);
  return (
  //  <Component1>
  //    <Component2>
  //      <Component3>
  //        <Component4>
  //          <Component5>
                <button onClick={() => setLanguage("jp")}>
                 Switch Language (Current: {language})
                </button>
  //          </Component5>
  //        </Component4>
  //      </Component3>
  //    </Component2>
  //  </Component1>
  );
};

export default LanguageSwitcher;

语言上下文.js

import React from "react";

// set the defaults
const LanguageContext = React.createContext({
  language: "en",
  setLanguage: () => {}
});

export default LanguageContext;

到目前为止一切正常,“语言”可以记录到根组件中的控制台,但如果我尝试将它作为参数传递给视频,则不会发生更新。点击后如何启动视频?

4

1 回答 1

0

我使用 [ref] (https://reactjs.org/docs/refs-and-the-dom.html#the-ref-string-attribute) 在 [this post][1] 中找到了答案,(上下文和状态不是问题,它们按预期工作)。在您的父组件中添加:

const vidRef = useRef();
const previousUrl = useRef(initState.language);
React.useEffect(() => {
    if (previousUrl.current === initState.language) {
      return;
    }

    if (vidRef.current) {
      vidRef.current.load();
    }

    previousUrl.current = initState.language;
  }, [initState.language]);

在视频元素中

<VideoWrapper>
   <Video  fit='cover' controls='over' ref={vidRef} autoPlay>
     <source key='video' src='somevideo.mp4' type='video/mp4' />
       <track
          key='cc'
          label='English'
          kind='subtitles'
          srcLang={urlstate.language}
          src='//v2.grommet.io/assets/small-en.vtt'
          default={true}
       />
   </Video>
</VideoWrapper>



     


  [1]: https://stackoverflow.com/questions/41303012/updating-source-url-on-html5-video-with-react
于 2021-05-20T10:48:38.203 回答