Tobi
Tobi

Reputation: 93

React Contextprovider force update Video Element to play Video

I'm using the React Context like this and got really stuck in how to update my video element (to play the video). Shouldn't the components update automatically when receiving the prop?

Heres a simplified version of my code:


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);

And the (in my case very nested) child component

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;

the language-context.js

import React from "react";

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

export default LanguageContext;

Everything works so far, the "language" can be logged to the console in the root component, but if i try to pass it as a param to the video, no update takes place. What to do to start the video after click?

Upvotes: 1

Views: 378

Answers (1)

Tobi
Tobi

Reputation: 93

I found the Answer in [this post][1] using [ref] (https://reactjs.org/docs/refs-and-the-dom.html#the-ref-string-attribute), (the context and states weren't the problem, they worked as expected). In your parent component add:

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]);

And in the videoelement

<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

Upvotes: 1

Related Questions