I want to create a reusable ponent where the DOM structure can be different each time the ponent is rendered. Let's say I have this
class Comp extends React.Component {
constructor() {
super()
this.state = {
click: null,
}
}
render() {
return(
<div>
{this.props.chidren}
</div>
)
}
handleButton1() {
this.setState({click: 'button1'});
}
handleButton2() {
this.setState({click: 'button2'});
}
}
class SubComp1 extends React.Component {
render() {
return(
<button onClick={() => this.props.handleButton1()}>Button 1</button>
)
}
}
class SubComp2 extends React.Component {
render() {
return (
<button onClick={() => this.props.handleButton2()}>Button 2</button>
)
}
}
ReactDOM.render((
<Comp>
<div id="somediv">
<div id="andanother">
<SubComp1 />
</div>
</div>
<div id="andanotherother">
<SubComp2 />
</div>
</Comp>), document.getElementById('app'))
Currently, the two subponents do not have access to their respective handler functions. What's the best way of passing the functions handleButton1
and handleButton2
to the subponents assuming that their position in the DOM is dynamic and might change depending on the layout of the page.
I have thought of 2 solutions so far:
Iterating inside the
props.children
until I find the element of interest then clone it with the propertyUsing
ref
and somehow render the subponents after the main ponent has been rendered through theponentDidMount
callback.
What are your thoughts on this?
I want to create a reusable ponent where the DOM structure can be different each time the ponent is rendered. Let's say I have this
class Comp extends React.Component {
constructor() {
super()
this.state = {
click: null,
}
}
render() {
return(
<div>
{this.props.chidren}
</div>
)
}
handleButton1() {
this.setState({click: 'button1'});
}
handleButton2() {
this.setState({click: 'button2'});
}
}
class SubComp1 extends React.Component {
render() {
return(
<button onClick={() => this.props.handleButton1()}>Button 1</button>
)
}
}
class SubComp2 extends React.Component {
render() {
return (
<button onClick={() => this.props.handleButton2()}>Button 2</button>
)
}
}
ReactDOM.render((
<Comp>
<div id="somediv">
<div id="andanother">
<SubComp1 />
</div>
</div>
<div id="andanotherother">
<SubComp2 />
</div>
</Comp>), document.getElementById('app'))
Currently, the two subponents do not have access to their respective handler functions. What's the best way of passing the functions handleButton1
and handleButton2
to the subponents assuming that their position in the DOM is dynamic and might change depending on the layout of the page.
I have thought of 2 solutions so far:
Iterating inside the
props.children
until I find the element of interest then clone it with the propertyUsing
ref
and somehow render the subponents after the main ponent has been rendered through theponentDidMount
callback.
What are your thoughts on this?
Share Improve this question edited Jul 12, 2017 at 20:56 Binyuan Sun asked Jul 12, 2017 at 20:31 Binyuan SunBinyuan Sun 1461 silver badge9 bronze badges 1- 1 Could you highlight your problem? – divine Commented Jul 12, 2017 at 20:50
3 Answers
Reset to default 2This is a place where using React's Context would be the most straightforward solution.
Another solution would be to use Redux actions, but that would make your ponent less reusable and more tightly coupled with your application, which you may or may not care about.
Why not do something like this:
class Comp extends React.Component {
constructor() {
super()
this.state = {
click: null,
}
}
render() {
return(
<div>
{this.props.chidren}
</div>
)
}
handleButton(button) {
this.setState({click: button});
}
}
Then in the subponents you can do something like
class SubComp1 extends React.Component {
render() {
return(
<button onClick={() => this.props.handleButton('button1')}>Button 1</button>
)
}
}
class SubComp2 extends React.Component {
render() {
return (
<button onClick={() => this.props.handleButton('button2')}>Button 2</button>
)
}
}
One Alternative option which might fit your needs is to build a higher order ponent, which decorates another ponent with some additional functionality, below is a quick example of how this may work for you,
The higher order ponent:
const Comp = ComposedComponent =>
class Comp extends React.Component {
constructor(props) {
super(props)
this.handleButton = this.handleButton.bind(this);
this.state = {
click: null,
}
}
handleButton(button) {
this.setState({click: button});
}
render() {
return(
<ComposedComponent
onClick={this.handleButton}
/>
)
}
}
export default Comp;
The child ponent:
class SubComp1 extends React.Component {
render() {
return(
<button onClick={() => this.props.onClick('button1')}>Button 1</button>
)
}
}
How to use it:
const ExtendedComp = Comp(SubComp1);
<ExtendedComp />
would this be suitable for your task?