1
votes

I have a Parent component which includes a Child component and passes it some render props.

const Parent = () => {
    return(
        <div>
            <h1>Title</h1>
            <Child>
                Text that I want
            </Child>
        </div>
    )
}

class Child extends React.Component{
    handleClick() {
        console.log('Hi')
    }
    render() {
        return(
            {this.props.children}
        )
    }
}

How can I make it so when the render props content "Text that I want" is clicked the Child's handleClick function is executed?

3
what would you want to do if you render multiple elements as children to Child component - Shubham Khatri
I wont need to do that. My actual use case is I have a mutation in Apollo that I need to use in different components. I will only ever render one Component within Child. - Evanss

3 Answers

1
votes

Wrap children in Child component with an element and pass it your event handler:

render() {
    return(
        <div onClick={() => this.handleClick()}> 
            {this.props.children}
        </div>
    )
}
1
votes

You could simply make use of React.cloneElement if this.props.children is anything other than a string or else wrap the text within span and attach the handler to it

const Parent = () => {
  return (
    <div>
      <h1>Title</h1>
      <Child>
        Text that I want
      </Child>
    </div>
  )
}

class Child extends React.Component {
  handleClick() {
    console.log('Hi')
  }
  render() {
    console.log(this.props.children)
    if(typeof this.props.children === 'string') {
      return <span onClick={this.handleClick}>{this.props.children}</span>
    }
    return React.cloneElement(this.props.children, {
      onClick: this.handleClick
    });
  }
}

Working sandbox

0
votes

Like this?

class Child extends React.Component{
    handleClick() {
        console.log('Hi')
    }
    render() {
        // pass click handler as an argument to function
        return this.props.children(this.handleClick.bind(this));
    }
}

const Parent = () => (
    <div>
       <h1>Title</h1>
       <Child>
         // use click handle passed as argument
         {clickHandler => <p onClick={clickHandler}>Text that I want</p>}
       </Child>
    </div>
)

because you can't have any events coming from a bare text you need a tag like p to attach it.