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







                      這個網誌中的熱門文章

                      Barbados

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      Node.js Script on GitHub Pages or Amazon S3