2

I am dynamically rendering react components as:

{map.call(this.state.text, (c, i) => (<Char
              click={() => this.deleteCharHandler(i)}
              charVal={c}
              key={i}/>))}

Where there render method of the Char component is:

 render() {
        return(
            <div className="char" onClick={this.props.click}>
                {this.props.charVal}
            </div>
        )

That works and deleteCharHandler is appropriately called with the correct value of i.

However, I would like to avoid having to pass the handler function as a prop. After all, onClick of the div is simply executing the click property, which is an anonymous function calling deleteCharHandler. I tried to refactor as:

{map.call(this.state.text, (c, i) => (<Char
              onClick={() => this.deleteCharHandler(i)}
              charVal={c}
              key={i}/>))}

Thus adding a react event listener to the Char element. And removed the onClick listener from the div in the Char component.

...And it doesn't work.

Why? Am I not just moving the onClick listener one level up?

3
  • DOM events are only fired from DOM elements. The Chars representation in the dom is what gets returned from its render method and in there you can add DOM event handlers. The onClick on Char is just another property passed down, it has no functionality on its own. Commented May 15, 2020 at 9:47
  • 1
    @GabrielePetrioli that's a cryptic answer if I saw one. Commented May 15, 2020 at 9:48
  • 1
    lol, indeed. added a small addition (if that helps) Commented May 15, 2020 at 9:49

1 Answer 1

2

You must note that passing any function to a React component is just passed down as a prop and not treated as a event listener. In order for the onClick to work it needs to be passed on to the DOM

Now either you can explicitly pass it on to div within Char component like do

 render() {
    return(
        <div className="char" onClick={this.props.click}>
            {this.props.charVal}
        </div>
    )

or you can destructure the other values and pass on the rest values using rest spread syntax. Either way you need to pass the handler to the DOM element

render() {
    const {charVal, ...rest} = this.props; 
    return(
        <div className="char" {...rest}>
            {charVal}
        </div>
    )

The above method gives you the flexibility to pass on props required to the div element without having to mention them explicitly. However you must be careful that you aren't passing non required values to the div element

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.