How to add React components dynamically without reload?












1















Context



Newer to React; I have a parent component that is generating anywhere from 1-6 youtube videos, using react-youtube components. The Idea is that the YouTube components will be generated dynamically based on youtube video ids in an array. Currently, I'm generating the components like



{this.state.videoIds.map((videoId, index) =>
<YouTube
key={index}
opts={opts}
videoId={videoId}
onReady={this._onReady} />
)}


As far as generating the components, it's working as expected. However, the issue is, when this.state.videoIds gets updated, it causes all of the YouTube components to be refreshed. That behavior makes sense to me.



Issue



The issue I have is the following: If the functionality stays the same, I need a way to be able to track each of the YouTube components player time, so that if a refresh happens, I can pass that data back down to the components when they are refreshed so they are able to be played from where they left off.



So my question is, is there a way to dynamically generate these components without needing to refresh all of the existing components?



For what it's worth, I have thought about just having a parent component that will statically add the components for each use case, but that seems awfully clunky, and I don't really want to go that route.



Edit



This feels relevant, I'm divvying up the screen space evenly based on how many players are loaded at any given time, code looks like the following:



calculateVideoWidth = () => {
if (this.state.videoIds.length <= 3) {
return (document.body.clientWidth - 15) / this.state.videoIds.length;
} else {
return (document.body.clientWidth - 15) / this.MAX_NUMBER_OF_COLUMNS;
}
};

calculateVideoHeight = () => {
if (this.state.videoIds.length <= 3) {
return window.innerHeight - 4;
} else {
return (window.innerHeight - 4) / this.MAX_NUMBER_OF_ROWS;
}
};


In my render method, I'm doing the following:



let opts = {
height: this.calculateVideoHeight(),
width: this.calculateVideoWidth()
};


After looking at @Tholle's comment, it occurs to me that the 'reload' is coming from the resizing. Which I guess makes sense. There has to be a better way to do this?



Edit 1



Check out this link to see what I am experiencing: Video App. In the input box, just add a video id separated by a ','.










share|improve this question

























  • How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

    – Tholle
    Nov 13 '18 at 17:17






  • 1





    Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

    – Sung Kim
    Nov 13 '18 at 17:33













  • @Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

    – ndland
    Nov 13 '18 at 17:44













  • I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

    – Tholle
    Nov 13 '18 at 18:09











  • I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

    – Jonas Høgh
    Nov 13 '18 at 18:12
















1















Context



Newer to React; I have a parent component that is generating anywhere from 1-6 youtube videos, using react-youtube components. The Idea is that the YouTube components will be generated dynamically based on youtube video ids in an array. Currently, I'm generating the components like



{this.state.videoIds.map((videoId, index) =>
<YouTube
key={index}
opts={opts}
videoId={videoId}
onReady={this._onReady} />
)}


As far as generating the components, it's working as expected. However, the issue is, when this.state.videoIds gets updated, it causes all of the YouTube components to be refreshed. That behavior makes sense to me.



Issue



The issue I have is the following: If the functionality stays the same, I need a way to be able to track each of the YouTube components player time, so that if a refresh happens, I can pass that data back down to the components when they are refreshed so they are able to be played from where they left off.



So my question is, is there a way to dynamically generate these components without needing to refresh all of the existing components?



For what it's worth, I have thought about just having a parent component that will statically add the components for each use case, but that seems awfully clunky, and I don't really want to go that route.



Edit



This feels relevant, I'm divvying up the screen space evenly based on how many players are loaded at any given time, code looks like the following:



calculateVideoWidth = () => {
if (this.state.videoIds.length <= 3) {
return (document.body.clientWidth - 15) / this.state.videoIds.length;
} else {
return (document.body.clientWidth - 15) / this.MAX_NUMBER_OF_COLUMNS;
}
};

calculateVideoHeight = () => {
if (this.state.videoIds.length <= 3) {
return window.innerHeight - 4;
} else {
return (window.innerHeight - 4) / this.MAX_NUMBER_OF_ROWS;
}
};


In my render method, I'm doing the following:



let opts = {
height: this.calculateVideoHeight(),
width: this.calculateVideoWidth()
};


After looking at @Tholle's comment, it occurs to me that the 'reload' is coming from the resizing. Which I guess makes sense. There has to be a better way to do this?



Edit 1



Check out this link to see what I am experiencing: Video App. In the input box, just add a video id separated by a ','.










share|improve this question

























  • How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

    – Tholle
    Nov 13 '18 at 17:17






  • 1





    Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

    – Sung Kim
    Nov 13 '18 at 17:33













  • @Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

    – ndland
    Nov 13 '18 at 17:44













  • I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

    – Tholle
    Nov 13 '18 at 18:09











  • I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

    – Jonas Høgh
    Nov 13 '18 at 18:12














1












1








1








Context



Newer to React; I have a parent component that is generating anywhere from 1-6 youtube videos, using react-youtube components. The Idea is that the YouTube components will be generated dynamically based on youtube video ids in an array. Currently, I'm generating the components like



{this.state.videoIds.map((videoId, index) =>
<YouTube
key={index}
opts={opts}
videoId={videoId}
onReady={this._onReady} />
)}


As far as generating the components, it's working as expected. However, the issue is, when this.state.videoIds gets updated, it causes all of the YouTube components to be refreshed. That behavior makes sense to me.



Issue



The issue I have is the following: If the functionality stays the same, I need a way to be able to track each of the YouTube components player time, so that if a refresh happens, I can pass that data back down to the components when they are refreshed so they are able to be played from where they left off.



So my question is, is there a way to dynamically generate these components without needing to refresh all of the existing components?



For what it's worth, I have thought about just having a parent component that will statically add the components for each use case, but that seems awfully clunky, and I don't really want to go that route.



Edit



This feels relevant, I'm divvying up the screen space evenly based on how many players are loaded at any given time, code looks like the following:



calculateVideoWidth = () => {
if (this.state.videoIds.length <= 3) {
return (document.body.clientWidth - 15) / this.state.videoIds.length;
} else {
return (document.body.clientWidth - 15) / this.MAX_NUMBER_OF_COLUMNS;
}
};

calculateVideoHeight = () => {
if (this.state.videoIds.length <= 3) {
return window.innerHeight - 4;
} else {
return (window.innerHeight - 4) / this.MAX_NUMBER_OF_ROWS;
}
};


In my render method, I'm doing the following:



let opts = {
height: this.calculateVideoHeight(),
width: this.calculateVideoWidth()
};


After looking at @Tholle's comment, it occurs to me that the 'reload' is coming from the resizing. Which I guess makes sense. There has to be a better way to do this?



Edit 1



Check out this link to see what I am experiencing: Video App. In the input box, just add a video id separated by a ','.










share|improve this question
















Context



Newer to React; I have a parent component that is generating anywhere from 1-6 youtube videos, using react-youtube components. The Idea is that the YouTube components will be generated dynamically based on youtube video ids in an array. Currently, I'm generating the components like



{this.state.videoIds.map((videoId, index) =>
<YouTube
key={index}
opts={opts}
videoId={videoId}
onReady={this._onReady} />
)}


As far as generating the components, it's working as expected. However, the issue is, when this.state.videoIds gets updated, it causes all of the YouTube components to be refreshed. That behavior makes sense to me.



Issue



The issue I have is the following: If the functionality stays the same, I need a way to be able to track each of the YouTube components player time, so that if a refresh happens, I can pass that data back down to the components when they are refreshed so they are able to be played from where they left off.



So my question is, is there a way to dynamically generate these components without needing to refresh all of the existing components?



For what it's worth, I have thought about just having a parent component that will statically add the components for each use case, but that seems awfully clunky, and I don't really want to go that route.



Edit



This feels relevant, I'm divvying up the screen space evenly based on how many players are loaded at any given time, code looks like the following:



calculateVideoWidth = () => {
if (this.state.videoIds.length <= 3) {
return (document.body.clientWidth - 15) / this.state.videoIds.length;
} else {
return (document.body.clientWidth - 15) / this.MAX_NUMBER_OF_COLUMNS;
}
};

calculateVideoHeight = () => {
if (this.state.videoIds.length <= 3) {
return window.innerHeight - 4;
} else {
return (window.innerHeight - 4) / this.MAX_NUMBER_OF_ROWS;
}
};


In my render method, I'm doing the following:



let opts = {
height: this.calculateVideoHeight(),
width: this.calculateVideoWidth()
};


After looking at @Tholle's comment, it occurs to me that the 'reload' is coming from the resizing. Which I guess makes sense. There has to be a better way to do this?



Edit 1



Check out this link to see what I am experiencing: Video App. In the input box, just add a video id separated by a ','.







javascript reactjs youtube-iframe-api






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 17:57







ndland

















asked Nov 13 '18 at 17:04









ndlandndland

1961314




1961314













  • How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

    – Tholle
    Nov 13 '18 at 17:17






  • 1





    Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

    – Sung Kim
    Nov 13 '18 at 17:33













  • @Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

    – ndland
    Nov 13 '18 at 17:44













  • I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

    – Tholle
    Nov 13 '18 at 18:09











  • I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

    – Jonas Høgh
    Nov 13 '18 at 18:12



















  • How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

    – Tholle
    Nov 13 '18 at 17:17






  • 1





    Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

    – Sung Kim
    Nov 13 '18 at 17:33













  • @Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

    – ndland
    Nov 13 '18 at 17:44













  • I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

    – Tholle
    Nov 13 '18 at 18:09











  • I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

    – Jonas Høgh
    Nov 13 '18 at 18:12

















How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

– Tholle
Nov 13 '18 at 17:17





How are you adding the new ids to the videoIds array? It doesn't seem to be refreshing in my simple example, but I might be misunderstanding you.

– Tholle
Nov 13 '18 at 17:17




1




1





Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

– Sung Kim
Nov 13 '18 at 17:33







Just throwing out an idea. Wrap <YouTube /> in another component extending PureComponent so that update only occurs when videoId of that component is updated?

– Sung Kim
Nov 13 '18 at 17:33















@Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

– ndland
Nov 13 '18 at 17:44







@Tholle, looks like the issue I'm having has to do more with the layout. Based on the number of players on the screen, I'm dividing up the visible screen space to the players evenly. In my render method, I have a function call for height and width. See my edits in the question.

– ndland
Nov 13 '18 at 17:44















I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

– Tholle
Nov 13 '18 at 18:09





I don't quite understand the layout you want to achieve, but can it not be achieved with CSS with e.g. Flexbox?

– Tholle
Nov 13 '18 at 18:09













I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

– Jonas Høgh
Nov 13 '18 at 18:12





I think a better approach would be to drop the hardcoded height and width and put the iframes in div containers and style those for a proper n-column layout. There are plenty of "responsive YouTube iframe" tutorials to be found on google such as this one google.dk/amp/s/benmarshall.me/responsive-iframes/amp

– Jonas Høgh
Nov 13 '18 at 18:12












2 Answers
2






active

oldest

votes


















0














This code might help you to start video from wherever user left.
The thing is we need to maintain or store the last played state of video wherever user left, some where permanently not erasable on reload, so here implemented using localStorage.



import React from "react";
import ReactDOM from "react-dom";
import YouTube from "react-`enter code here`youtube";

class App extends React.Component {
state = {
videoIds: ["2g811Eo7K8U"],
videosPlayState: {}
};

componentDidMount() {
let videosPlayState = localStorage.getItem("videosPlayState") || "{}";
this.setState({
videosPlayState: JSON.parse(videosPlayState)
});
}

addVideo = () => {
this.setState(prevState => ({
videoIds: [...prevState.videoIds, "9kBACkguBR0"]
}));
};

_onStateChange = (event, videoId) => {
let newPlayState = { ...this.state.videosPlayState
};
newPlayState[videoId] = event.target.getCurrentTime();
localStorage.setItem("videosPlayState", JSON.stringify(newPlayState));
};

_onReady(event, videoId) {
event.target.seekTo(this.state.videosPlayState[videoId] || 0);
}
render() {
const opts = {
height: "200",
width: "400",
playerVars: {
autoplay: 1
}
};
return ( <
div className = "App" >
<
div className = "video-container" > {
this.state.videoIds.map((videoId, index) => ( <
YouTube onStateChange = {
event => {
this._onStateChange(event, videoId);
}
}
onReady = {
event => {
this._onReady(event, videoId);
}
}
key = {
index
}
videoId = {
videoId
}
opts = {
opts
}
className = {
"item"
}
/>
))
} <
/div> <
div >
<
button onClick = {
this.addVideo
} > Add video < /button> <
/div> <
/div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render( < App / > , rootElement);


here is the css:



.video-container .item {
padding: 25px;
display: inline-block;
}
.video-container {
display: flex;
flex-wrap: wrap;
}


here is a link might help you enter link description here






share|improve this answer

































    0














    After playing with flexbox a bit more, I was able to solve this issue. I ended up with the following:



    html, body, #root, #root > div, div.container, iframe {
    width: 100%;
    height: 100%;
    margin: 0;
    }

    div.container {
    display: flex;
    flex-wrap: wrap;
    }

    span {
    flex-basis: 33%;
    flex-grow: 1;
    }


    For reference, here is my jsx



            <div>
    <div className="container">
    {this.state.videoIds.map((videoId, index) =>
    <YouTube
    id="flex-item"
    key={index}
    videoId={videoId}
    onStateChange={this._onStateChange}
    onReady={this._onReady}/>
    )}
    </div>
    </div>


    I figured this could be done with flexbox, but I hadn't come up with the solution for it yet. I hope this helps someone else out.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53286135%2fhow-to-add-react-components-dynamically-without-reload%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      This code might help you to start video from wherever user left.
      The thing is we need to maintain or store the last played state of video wherever user left, some where permanently not erasable on reload, so here implemented using localStorage.



      import React from "react";
      import ReactDOM from "react-dom";
      import YouTube from "react-`enter code here`youtube";

      class App extends React.Component {
      state = {
      videoIds: ["2g811Eo7K8U"],
      videosPlayState: {}
      };

      componentDidMount() {
      let videosPlayState = localStorage.getItem("videosPlayState") || "{}";
      this.setState({
      videosPlayState: JSON.parse(videosPlayState)
      });
      }

      addVideo = () => {
      this.setState(prevState => ({
      videoIds: [...prevState.videoIds, "9kBACkguBR0"]
      }));
      };

      _onStateChange = (event, videoId) => {
      let newPlayState = { ...this.state.videosPlayState
      };
      newPlayState[videoId] = event.target.getCurrentTime();
      localStorage.setItem("videosPlayState", JSON.stringify(newPlayState));
      };

      _onReady(event, videoId) {
      event.target.seekTo(this.state.videosPlayState[videoId] || 0);
      }
      render() {
      const opts = {
      height: "200",
      width: "400",
      playerVars: {
      autoplay: 1
      }
      };
      return ( <
      div className = "App" >
      <
      div className = "video-container" > {
      this.state.videoIds.map((videoId, index) => ( <
      YouTube onStateChange = {
      event => {
      this._onStateChange(event, videoId);
      }
      }
      onReady = {
      event => {
      this._onReady(event, videoId);
      }
      }
      key = {
      index
      }
      videoId = {
      videoId
      }
      opts = {
      opts
      }
      className = {
      "item"
      }
      />
      ))
      } <
      /div> <
      div >
      <
      button onClick = {
      this.addVideo
      } > Add video < /button> <
      /div> <
      /div>
      );
      }
      }
      const rootElement = document.getElementById("root");
      ReactDOM.render( < App / > , rootElement);


      here is the css:



      .video-container .item {
      padding: 25px;
      display: inline-block;
      }
      .video-container {
      display: flex;
      flex-wrap: wrap;
      }


      here is a link might help you enter link description here






      share|improve this answer






























        0














        This code might help you to start video from wherever user left.
        The thing is we need to maintain or store the last played state of video wherever user left, some where permanently not erasable on reload, so here implemented using localStorage.



        import React from "react";
        import ReactDOM from "react-dom";
        import YouTube from "react-`enter code here`youtube";

        class App extends React.Component {
        state = {
        videoIds: ["2g811Eo7K8U"],
        videosPlayState: {}
        };

        componentDidMount() {
        let videosPlayState = localStorage.getItem("videosPlayState") || "{}";
        this.setState({
        videosPlayState: JSON.parse(videosPlayState)
        });
        }

        addVideo = () => {
        this.setState(prevState => ({
        videoIds: [...prevState.videoIds, "9kBACkguBR0"]
        }));
        };

        _onStateChange = (event, videoId) => {
        let newPlayState = { ...this.state.videosPlayState
        };
        newPlayState[videoId] = event.target.getCurrentTime();
        localStorage.setItem("videosPlayState", JSON.stringify(newPlayState));
        };

        _onReady(event, videoId) {
        event.target.seekTo(this.state.videosPlayState[videoId] || 0);
        }
        render() {
        const opts = {
        height: "200",
        width: "400",
        playerVars: {
        autoplay: 1
        }
        };
        return ( <
        div className = "App" >
        <
        div className = "video-container" > {
        this.state.videoIds.map((videoId, index) => ( <
        YouTube onStateChange = {
        event => {
        this._onStateChange(event, videoId);
        }
        }
        onReady = {
        event => {
        this._onReady(event, videoId);
        }
        }
        key = {
        index
        }
        videoId = {
        videoId
        }
        opts = {
        opts
        }
        className = {
        "item"
        }
        />
        ))
        } <
        /div> <
        div >
        <
        button onClick = {
        this.addVideo
        } > Add video < /button> <
        /div> <
        /div>
        );
        }
        }
        const rootElement = document.getElementById("root");
        ReactDOM.render( < App / > , rootElement);


        here is the css:



        .video-container .item {
        padding: 25px;
        display: inline-block;
        }
        .video-container {
        display: flex;
        flex-wrap: wrap;
        }


        here is a link might help you enter link description here






        share|improve this answer




























          0












          0








          0







          This code might help you to start video from wherever user left.
          The thing is we need to maintain or store the last played state of video wherever user left, some where permanently not erasable on reload, so here implemented using localStorage.



          import React from "react";
          import ReactDOM from "react-dom";
          import YouTube from "react-`enter code here`youtube";

          class App extends React.Component {
          state = {
          videoIds: ["2g811Eo7K8U"],
          videosPlayState: {}
          };

          componentDidMount() {
          let videosPlayState = localStorage.getItem("videosPlayState") || "{}";
          this.setState({
          videosPlayState: JSON.parse(videosPlayState)
          });
          }

          addVideo = () => {
          this.setState(prevState => ({
          videoIds: [...prevState.videoIds, "9kBACkguBR0"]
          }));
          };

          _onStateChange = (event, videoId) => {
          let newPlayState = { ...this.state.videosPlayState
          };
          newPlayState[videoId] = event.target.getCurrentTime();
          localStorage.setItem("videosPlayState", JSON.stringify(newPlayState));
          };

          _onReady(event, videoId) {
          event.target.seekTo(this.state.videosPlayState[videoId] || 0);
          }
          render() {
          const opts = {
          height: "200",
          width: "400",
          playerVars: {
          autoplay: 1
          }
          };
          return ( <
          div className = "App" >
          <
          div className = "video-container" > {
          this.state.videoIds.map((videoId, index) => ( <
          YouTube onStateChange = {
          event => {
          this._onStateChange(event, videoId);
          }
          }
          onReady = {
          event => {
          this._onReady(event, videoId);
          }
          }
          key = {
          index
          }
          videoId = {
          videoId
          }
          opts = {
          opts
          }
          className = {
          "item"
          }
          />
          ))
          } <
          /div> <
          div >
          <
          button onClick = {
          this.addVideo
          } > Add video < /button> <
          /div> <
          /div>
          );
          }
          }
          const rootElement = document.getElementById("root");
          ReactDOM.render( < App / > , rootElement);


          here is the css:



          .video-container .item {
          padding: 25px;
          display: inline-block;
          }
          .video-container {
          display: flex;
          flex-wrap: wrap;
          }


          here is a link might help you enter link description here






          share|improve this answer















          This code might help you to start video from wherever user left.
          The thing is we need to maintain or store the last played state of video wherever user left, some where permanently not erasable on reload, so here implemented using localStorage.



          import React from "react";
          import ReactDOM from "react-dom";
          import YouTube from "react-`enter code here`youtube";

          class App extends React.Component {
          state = {
          videoIds: ["2g811Eo7K8U"],
          videosPlayState: {}
          };

          componentDidMount() {
          let videosPlayState = localStorage.getItem("videosPlayState") || "{}";
          this.setState({
          videosPlayState: JSON.parse(videosPlayState)
          });
          }

          addVideo = () => {
          this.setState(prevState => ({
          videoIds: [...prevState.videoIds, "9kBACkguBR0"]
          }));
          };

          _onStateChange = (event, videoId) => {
          let newPlayState = { ...this.state.videosPlayState
          };
          newPlayState[videoId] = event.target.getCurrentTime();
          localStorage.setItem("videosPlayState", JSON.stringify(newPlayState));
          };

          _onReady(event, videoId) {
          event.target.seekTo(this.state.videosPlayState[videoId] || 0);
          }
          render() {
          const opts = {
          height: "200",
          width: "400",
          playerVars: {
          autoplay: 1
          }
          };
          return ( <
          div className = "App" >
          <
          div className = "video-container" > {
          this.state.videoIds.map((videoId, index) => ( <
          YouTube onStateChange = {
          event => {
          this._onStateChange(event, videoId);
          }
          }
          onReady = {
          event => {
          this._onReady(event, videoId);
          }
          }
          key = {
          index
          }
          videoId = {
          videoId
          }
          opts = {
          opts
          }
          className = {
          "item"
          }
          />
          ))
          } <
          /div> <
          div >
          <
          button onClick = {
          this.addVideo
          } > Add video < /button> <
          /div> <
          /div>
          );
          }
          }
          const rootElement = document.getElementById("root");
          ReactDOM.render( < App / > , rootElement);


          here is the css:



          .video-container .item {
          padding: 25px;
          display: inline-block;
          }
          .video-container {
          display: flex;
          flex-wrap: wrap;
          }


          here is a link might help you enter link description here







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 13 '18 at 19:35

























          answered Nov 13 '18 at 18:40









          Jaisa RamJaisa Ram

          22137




          22137

























              0














              After playing with flexbox a bit more, I was able to solve this issue. I ended up with the following:



              html, body, #root, #root > div, div.container, iframe {
              width: 100%;
              height: 100%;
              margin: 0;
              }

              div.container {
              display: flex;
              flex-wrap: wrap;
              }

              span {
              flex-basis: 33%;
              flex-grow: 1;
              }


              For reference, here is my jsx



                      <div>
              <div className="container">
              {this.state.videoIds.map((videoId, index) =>
              <YouTube
              id="flex-item"
              key={index}
              videoId={videoId}
              onStateChange={this._onStateChange}
              onReady={this._onReady}/>
              )}
              </div>
              </div>


              I figured this could be done with flexbox, but I hadn't come up with the solution for it yet. I hope this helps someone else out.






              share|improve this answer




























                0














                After playing with flexbox a bit more, I was able to solve this issue. I ended up with the following:



                html, body, #root, #root > div, div.container, iframe {
                width: 100%;
                height: 100%;
                margin: 0;
                }

                div.container {
                display: flex;
                flex-wrap: wrap;
                }

                span {
                flex-basis: 33%;
                flex-grow: 1;
                }


                For reference, here is my jsx



                        <div>
                <div className="container">
                {this.state.videoIds.map((videoId, index) =>
                <YouTube
                id="flex-item"
                key={index}
                videoId={videoId}
                onStateChange={this._onStateChange}
                onReady={this._onReady}/>
                )}
                </div>
                </div>


                I figured this could be done with flexbox, but I hadn't come up with the solution for it yet. I hope this helps someone else out.






                share|improve this answer


























                  0












                  0








                  0







                  After playing with flexbox a bit more, I was able to solve this issue. I ended up with the following:



                  html, body, #root, #root > div, div.container, iframe {
                  width: 100%;
                  height: 100%;
                  margin: 0;
                  }

                  div.container {
                  display: flex;
                  flex-wrap: wrap;
                  }

                  span {
                  flex-basis: 33%;
                  flex-grow: 1;
                  }


                  For reference, here is my jsx



                          <div>
                  <div className="container">
                  {this.state.videoIds.map((videoId, index) =>
                  <YouTube
                  id="flex-item"
                  key={index}
                  videoId={videoId}
                  onStateChange={this._onStateChange}
                  onReady={this._onReady}/>
                  )}
                  </div>
                  </div>


                  I figured this could be done with flexbox, but I hadn't come up with the solution for it yet. I hope this helps someone else out.






                  share|improve this answer













                  After playing with flexbox a bit more, I was able to solve this issue. I ended up with the following:



                  html, body, #root, #root > div, div.container, iframe {
                  width: 100%;
                  height: 100%;
                  margin: 0;
                  }

                  div.container {
                  display: flex;
                  flex-wrap: wrap;
                  }

                  span {
                  flex-basis: 33%;
                  flex-grow: 1;
                  }


                  For reference, here is my jsx



                          <div>
                  <div className="container">
                  {this.state.videoIds.map((videoId, index) =>
                  <YouTube
                  id="flex-item"
                  key={index}
                  videoId={videoId}
                  onStateChange={this._onStateChange}
                  onReady={this._onReady}/>
                  )}
                  </div>
                  </div>


                  I figured this could be done with flexbox, but I hadn't come up with the solution for it yet. I hope this helps someone else out.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 15 '18 at 17:28









                  ndlandndland

                  1961314




                  1961314






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53286135%2fhow-to-add-react-components-dynamically-without-reload%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values