Reputation: 1804
Is it possible to have a component with child components that will be mounted to different DOM objects?
Some pseudo-code to explain what I wanna archieve:
import ChildComponent1 from './Components/ChildComponent1';
import ChildComponent2 from './Components/ChildComponent2';
var MyParentComponent = React.createClass({
render: function() {
<ChildComponent1 />,
document.querySelector('#component-1')
<ChildComponent2 />,
document.querySelector('#component-2')
}
});
ReactDOM.render(
<MyParentComponent />,
//Inherit DOM mounts
);
This might not be the right way to handle it though - I'm open for suggestions. I want to do like this, to make MyParentComponent take care of the state values etc. If I just add multiple ReactDOM.render() I won't have any parent component.
Upvotes: 3
Views: 2922
Reputation: 14768
You can achieve this using the componentDidMount
and componentDidUpdate
hooks to manually render your child components when your parent component updates:
class Child1 extends React.Component {
render() {
const {count, onClick} = this.props;
return (
<div onClick={onClick}>Child 1 {count}</div>
);
}
}
class Child2 extends React.Component {
render() {
const {count, onClick} = this.props;
return (
<div onClick={onClick}>Child 2 {count}</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.container1El = document.querySelector("#container-1");
this.container2El = document.querySelector("#container-2");
this.handleClick = this.handleClick.bind(this);
this.state = {count: 0};
}
handleClick() {
this.setState({count: this.state.count + 1});
}
renderChildren() {
const {count} = this.state;
const {handleClick, container1El, container2El} = this;
ReactDOM.render(<Child1 count={count} onClick={handleClick}/>, container1El);
ReactDOM.render(<Child2 count={count} onClick={handleClick}/>, container2El);
}
componentDidMount() {
this.renderChildren();
}
componentDidUpdate() {
this.renderChildren();
}
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(this.container1El);
ReactDOM.unmountComponentAtNode(this.container2El);
}
render() {
return null;
}
}
ReactDOM.render(<App/>, document.createElement("div"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container-1"></div>
<div id="container-2"></div>
Upvotes: 2
Reputation: 92112
What you are looking for is a portal.
Sometimes it is useful to render a child element to a different dom tree than the natural one. For example you may want the child to get appended to body
, generally for z-index
or opacity
reasons.
I've described it here: https://stackoverflow.com/a/31563614/82609
Consider the following:
<div className="a">
a content
<Portal target="body">
<div className="b">
b content
</div>
</Portal>
</div>
Could produce the following DOM when rendered inside reactAppContainer
:
<body>
<div id="reactAppContainer">
<div className="a">
a content
</div>
</div>
<div className="b">
b content
</div>
</body>
Popular portal libraries are:
Upvotes: 2
Reputation: 281616
No need to create a parent component, you can use ReactDOM.render()
multiple times
import ChildComponent1 from './Components/ChildComponent1';
import ChildComponent2 from './Components/ChildComponent2';
ReactDOM.render(
<ChildComponent1 />,
document.getElementById('component-1')
);
ReactDOM.render(
<ChildComponent2 />,
document.getElementById('component-2')
);
UPDATE
In order to have multiple components in one you can have your structure as:
import ChildComponent1 from './Components/ChildComponent1';
import ChildComponent2 from './Components/ChildComponent2';
var MyParentComponent = React.createClass({
render: function() {
return(
<div>
<ChildComponent1 />
<div>Some text</div>
<div>Some more text</div>
<ChildComponent2 />
</div>
)}
});
ReactDOM.render(
<MyParentComponent />,
document.getElementById('app');
);
Upvotes: 0
Reputation: 745
The answer is no, it's not possible. This is the best you can do if you still want to use React for that.
var MyParentComponent = React.createClass({
render: function() {
<div>
{this.props.children}
<ChildComponent1 />
<ChildComponent2 />
</div>
}
});
ReactDOM.render(
<MyParentComponent />,
//Inherit DOM mounts
);
Upvotes: -1