3

enter image description hereI have a situation where I require to render two different components at two DIFFERENT ids. Something like this:

ReactDOM.render(
 <Component1/>,
document.getElementById('Coponent-id-1'));

and:

var deal_recommendations_id = document.getElementById('deal_recommendations_app');
       ReactDOM.render(
     <Component2/>,
    document.getElementById('Coponent-id-2'));

P.S This is different scenario than wrapping two component with a div and then rendering it on a single id

I'm actually trying to do this:

ReactDOM.render((
    <Provider store={store}>
        <Router history={hashHistory}>
            <Route path="/" component={WizardApp}> </Route>
             <Route path="/overview" component={DealRecommendation}></Route> 
             <Route path="/overview/:deal" component={DealRecommendation}></Route>         
            <Route path="/users/invite" component={ReferralApp}></Route> 
            <Route path="/adm/custodian" component={CustodianApp}></Route> 

        </Router>
    </Provider>
    ), document.getElementById('appRoot')
);
   var deal_recommendations_id = document.getElementById('deal_recommendations_app');
ReactDOM.render(
 <DealRecommendation/>,
deal_recommendations_id);

P.P.S In normal cases it works fine as shown in the answers. In my case, at deal_recommendations_id three Links(react Links) are loaded. when I click on any of these, I get an error message:

Link.js:95 Uncaught TypeError: Cannot read property 'pushState' of undefined

Here is the complete snippet:

   import React, { Component } from 'react';
import ReactDOM from "react-dom";

import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';

import rootReducer from './reducers';

// import App from './components/App';
import WizardApp from './components/WizardApp';
import DealRecommendation from './components/dealRecommendation';
import ReferralApp from './components/referral/ReferralApp';
import CustodianApp from './components/admin/custodian/CustodianApp';
import { Router, Route, IndexRoute, Link, browserHistory, hashHistory } from 'react-router'

const store = createStore(rootReducer,compose(
    applyMiddleware(thunk),
    window.devToolsExtension ? window.devToolsExtension() : f => f
));



ReactDOM.render((
    <Provider store={store}>
        <Router history={hashHistory}>
            <Route path="/" component={WizardApp}> </Route>
             <Route path="/overview" component={DealRecommendation}></Route> 
             <Route path="/overview/:deal" component={DealRecommendation}></Route>         
            <Route path="/users/invite" component={ReferralApp}></Route> 
            <Route path="/adm/custodian" component={CustodianApp}></Route> 

        </Router>
    </Provider>
    ), document.getElementById('appRoot')
);

var deal_recommendations_id = document.getElementById('deal_recommendations_app');
ReactDOM.render(
 <DealRecommendation/>,
deal_recommendations_id);

See the snapshot. The upper div works fine (in this case, this.props.params are getting populated too). However, the lower div which I think gets initialized even before the <Routers> are defined is causing the problem I think. (in this case, this.props.params is coming as undefined)

-------------------DealRecommendation.js------------------------------------

import React from "react";
import ReactDOM from "react-dom";
import { Router, Route, IndexRoute, Link, browserHistory, hashHistory } from 'react-router';
import { createHistory } from 'history';
import RouterTabs from "./dealsOfInterest/routerTabs"
import '../style/deal_recommendation.css';


export default class DealRecommendation extends React.Component{

  constructor(){
    super();
  }


  render(){
    if(this.props.params!=undefined){
    if(this.props.params.deal==="rec_act"){
       return(
        <div className="deal_data_wrapper">
          <h3>Deals of Interest</h3>
          <RouterTabs/>
          <h2>this is activity</h2>
        </div>
        )  
    }

    else if(this.props.params.deal==="deal_news"){
         return(
        <div className="deal_data_wrapper">
          <h3>Deals of Interest</h3>
          <RouterTabs/>
           <h2>This is Deal_news</h2>
        </div>
        )  

    }
    else{

         return(
        <div className="deal_data_wrapper">
          <h3>Deals of Interest</h3>
          <RouterTabs/>
           <h2>This works too</h2>
        </div>
        )  

      }
    }

    else{
         return(
        <div className="deal_data_wrapper">
          <h3>Deals of Interest</h3>
          <RouterTabs/>

          <h2>This doesn't work</h2>
        </div>
        )  
    }

  }
}
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
ABGR
  • 4,631
  • 4
  • 27
  • 49

2 Answers2

1

It is perfectly fine to use two ReactDOM.render() in a single script.

See example below

var Hello = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);
var HelloAgain = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(
  <HelloAgain name="World again" />,
  document.getElementById('another-container')
);

JSFIDDLE

Refer to the following articles

React Forum, SO POST

In your case

var deal_recommendations_id = document.getElementById('deal_recommendations_app');
ReactDOM.render(
 <DealRecommendation/>,
document.getElementById('deal_recommendations_id'));

deal_recommendation_id is already a DOM element and not an id you need not use document.getElementById again. Use it like below

var deal_recommendations_id = document.getElementById('deal_recommendations_app');
ReactDOM.render(
 <DealRecommendation/>,
deal_recommendations_id);

EDIT:

As far as I can see you need to remove the redundant route for dealrecommendation

ReactDOM.render((
    <Provider store={store}>
        <Router history={hashHistory}>
            <Route path="/" component={WizardApp}> </Route> 
             <Route path="/overview/:deal" component={DealRecommendation}></Route>         
            <Route path="/users/invite" component={ReferralApp}></Route> 
            <Route path="/adm/custodian" component={CustodianApp}></Route> 

        </Router>
    </Provider>
    ), document.getElementById('appRoot')
);
   var deal_recommendations_id = document.getElementById('deal_recommendations_app');
ReactDOM.render(
 <DealRecommendation/>,
deal_recommendations_id);
Community
  • 1
  • 1
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • yup. Corrected that mistake. I still get that error though :( – ABGR Sep 26 '16 at 07:15
  • A different error: Cannot read property 'pushState' of undefined – ABGR Sep 26 '16 at 07:19
  • are you using pushState anywhere in your code. Relating to react-router. Here is a SO question on this error. http://stackoverflow.com/questions/34145009/react-js-tests-typeerror-cannot-read-property-pushstate-of-undefined I suppose it has nothing to do with you original question. It arises because of a different problem. Although I am not sure. – Shubham Khatri Sep 26 '16 at 07:22
  • Yup I get it. The problem is different. Shall I change my question or the the edit is sufficient? – ABGR Sep 26 '16 at 07:41
  • 1
    Well as far as I would have suggested you a separate question for the current problem would have been more appropriate. My answer for you original question which is nowhere to be seen now after your edit. :) Anyways let me see the current problem – Shubham Khatri Sep 26 '16 at 08:23
0

Is this what you are after? http://codepen.io/PiotrBerebecki/pen/kkyYJv

The script tag to your js file should be put at the bottom of the body tag (below the targeted ids).

HTML:

<head>
  <title>React JS</title>
</head>

<body>
  <div id="app1"></div>
  <div id="app2"></div>

  <script src="/index.js"></script>
</body>

</html>

JS:

class Component1 extends React.Component {
  render() {
    return (
      <div>Hello React from Component 1</div>
    );
  }
}


class Component2 extends React.Component {
  render() {
    return (
      <div>Hello React from Component 2</div>
    );
  }
}


ReactDOM.render(
  <Component1 />,
  document.getElementById('app1')
);

ReactDOM.render(
  <Component2 />,
  document.getElementById('app2')
);
Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42
  • 1
    May be I oversimplified. I get this error: invariant.js:39 Uncaught Invariant Violation: _registerComponent(...): Target container is not a DOM element. Please see my updated question again – ABGR Sep 26 '16 at 07:05
  • I've just added info regarding where the script tag should be located. – Piotr Berebecki Sep 26 '16 at 07:12
  • The script tag should be at the bottom of the body tag. I've added explanation to the answer. – Piotr Berebecki Sep 26 '16 at 07:18