0

Coming from Vue.js (two way data flow) I have question about react one way data flow - I have a Parent that have a handler for its child onClick:

<div className="recipe-container">
                <button onClick={this.toggleRecipeList.bind(this)}>Show Recipes</button>
                <RecipeList showRecipe={this.showRecipe} list={this.state.recipes} />
            </div>

So, I pass showRecipe handler, which has only one parameter (and simply just logs it to the console).

My RecipeList looks like this (stateless func):

return (<ul className='recipe-list-bottom'>
        {
            props.list.map((rec, key) => {
                return <li onClick={props.showRecipe(rec)} key={key}>{rec.title}</li>
            })
        }

    </ul>)

I tried to launch showRecipe(rec) to have the current rec object as argument. Although I recive what I want, the handler is being fired from a button which is a sibling of RecipeList.

I manage to get it working by adding onClick={props.showRecipe.bind(null,rec)} to li element, but I find it really dirty way to do so.

Am I missing something? I thought showRecipe(rec) would be enough to get what I wanted. Why showRecipe(rec) is being fired with this set to button?

2 Answers 2

2

I think that your second snippet has a classic error:

return (<ul className='recipe-list-bottom'>
        {
            props.list.map((rec, key) => {
                return <li onClick={props.showRecipe(rec)/*here*/} key={key}>{rec.title}</li>
            })
        }

    </ul>)

You are assigning the result of calling showRecipe to the onClick parameter, not the function itself. The bind solutions works, but if you want to pass the parameter rec without using bind you need to wrap the call:

return (<ul className='recipe-list-bottom'>
        {
            props.list.map((rec, key) => {
                return <li onClick={()=>props.showRecipe(rec)} key={key}>{rec.title}</li>
            })
        }

    </ul>)
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, it does work! Silly me, idk why I thought it will be fired with that parameter :D. Thanks! Beginner's mistake.
1

You can use es2015 stage-0 syntax in order to write it like this:

class Blah extends Component {
  onClick = (recipe) => e => this.props.showRecipe(recipe);

  render() { 
    return (
      <ul className='recipe-list-bottom'>
        {
            props.list.map((rec, key) => {
                return <li onClick={onClick(rec)} key={key}>{rec.title}</li>
            })
        }

      </ul>
    )
  }
}

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.