3

I am new to React and trying to learn the framework from the ground up. I have built a few simple components(for a typical restaurant website), but I am facing problems understanding event handling. Basically, I have an app component which just calls the Main component, which in turn calls a Menu and Dishdetail component. So the hierarchy is App --> Main --> (Menu and Dishdetail).

App (Just call Main)

return (
  <div>
    **<Main/>**
  </div>
);

Main (Calling Menu component with props) Here I use the onClick event.

  **<Menu dishes={this.state.dishes}
                onClick={(dishId) => this.onDishSelect(dishId)} />**

Menu (Using the onClick event to render something using the RenderMenuItem functional component)

const menu = props.dishes.map((dish) => {
    return (
        <div key={dish.id} className="col-12 col-md-5 mt-5 m-1">
            **<RenderMenuItem dish={dish} onClick={props.onClick} />**
        </div>
    )
});

The RenderMenuItem functional component:

function RenderMenuItem({ dish, **onClick** }) {
return (
    **<Card onClick={() => onClick(dish.id)}>**
        <CardImg width='100%' src={dish.image} alt={dish.name} />
        <CardImgOverlay>
            <CardTitle>{dish.name}</CardTitle>
        </CardImgOverlay>
    </Card>
)}

Everything is working fine but I am having problems understanding the event handler and I'm also new to arrow functions. According to my understanding:

  1. App calls the Main component which in turn calls the menu component with the 2 props. Here I use the arrow function as a response to onClick event to set the state of the component. ( So I know which dish is selected). But I am also passing it as a prop? Or am I not?

  2. Once the execution flows into the Menu component it calls the RenderMenuItem with the dish selected in the map 'loop' and the same prop onClick it received. What is going on here? Is it just instructing the program to call the function in the Main component (just change state again as in point 1)?

  3. In the RenderMenuItem component I have no idea what is going on with the onClick attribute aside from the fact that it is calling a function called onClick with parameter dish.id. Can someone explain in detail what exactly happens when you pass an event attribute like onClick to child components?

1
  • You are dealing with lots of new concepts at the same time, the two main concets that you will need to understand are Reactjs and Vanilla Javascript ES6 standards. Learning how to use React goes along with VJS-ES6. I personally found this video tutorial series really good at explaning Reactjs step by step youtube.com/… Commented Dec 17, 2019 at 7:43

1 Answer 1

1

In your code, onClick is both event handler and prop. Do not use onClick as a prop.

  1. Yes the onClick() is also passed down to child components like any other prop.

  2. You have again passed the onClick you received in the Menu component as a prop on to the RenderMenuItem component. When Menu component is clicked, props.onClick function will be called with click event. Check the following example code

function Welcome(props) {
  return <h1 onClick={props.onClick}>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" onClick={(id)=>{ console.log(id) }}/>;
ReactDOM.render(element, document.getElementById('root'));

But you cannot pass an actual prop to that function in this state, for that you have to wrap it within an arrow function, which is exactly what you have done in RenderMenuItem component.

function Welcome(props) {
  return <h1 onClick={() => {props.onClick(12)}>Hello, {props.name}</h1>;
}

If your intention is just to pass the function to child component, use a different prop name other than onClick.

const menu = props.dishes.map((dish) => {
    return (
        <div key={dish.id} className="col-12 col-md-5 mt-5 m-1">
            **<RenderMenuItem dish={dish} clickHandler={props.onClick} />**
        </div>
    )
});

P.s. Do not use arrow functions in render, it will create new function on each render. Bind a function with the class controller and use it in render.

class Example extends Component {
  constructor(props, context) {
    super(props, context);
    this.clickHandler = this.clickHandler.bind(this); 
  }
  clickHandler(id) { // Use curried function if you need event clickHandler = (id) => (event) => {} 
 // do something
  }
  render() {
    return (
        <div onClick={this.clickHandler(2)}></div>
    );
  }
}
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.