Hi! I’m a bit confused why your code work and mine doesn’t. We did almost the same thing, but a added the handleClick in App.js instead GroceryItem.js, then used onClick={handleClick} at each
The click works fine, but at the alert message, the ${item} doesn’t show up, and the message that pops up is “[object Object] has been added to the cart.”
Here is my code for App.js:
import React from 'react';
import GroceryItem from './GroceryItem';
function App() {
function handleClick(item) {
alert(`${item} has been added to the cart.`);
}
return (
<div>
<GroceryItem item="Eggs" onClick={handleClick}/>
<GroceryItem item="Banana" onClick={handleClick}/>
<GroceryItem item="Strawberry" onClick={handleClick}/>
<GroceryItem item="Bread" onClick={handleClick}/>
</div>
);
}
export default App
Here is my code for GroceryItem.js
import React from 'react';
function GroceryItem(props) {
return (
<button onClick={props.onClick}>{props.item}</button>
);
}
export default GroceryItem;
For your proposed alternative solution, you could try the following.
In GroceryItem.js,
// You wrote:
<button onClick={props.onClick}>{props.item}</button>
// Try changing it to:
<button onClick={()=>props.onClick(props.item)}>{props.item}</button>
As for the '[object Object] has been added to the cart.' message, that object is most likely the SyntheticEvent:
Actually, just using a function inside onClick of GroceryItem, worked and logged the correct message with the clicked item being displayed. I think I understood… I need to pass this function inside the onClick to pass the props.item to the event handler, so it can alert with the correct ${item}, right?
Hey! I really did struggle with this but after watching a few extra videos on YouTube, I have finally come to this solution and understanding. I hope this explanation helps those who it needs to help. Within App.js:
import React from 'react';
function GroceryItem({item}) {
function handleClick() {
alert(`${item} added to the cart!`);
}
return (
<button onClick={handleClick}>
{item}
</button>
);
};
// Can also be written as follows:
// function GroceryItem(props) {
// function handleClick() {
// alert(`${props.item} added to the cart!`);
// }
// return (
// <button onClick={handleClick}>
// {props.item}
// </button>
// );
// };
// OR! If you'd like to read my conclusion to follow, here is - in my opinion,
// a more readable and self-explanatory solution for people of all levels to
// understand... And it looks as follows:
// function GroceryItem(GroceryProps) {
// function handleClick() {
// alert(`${GroceryProps.item} added to the cart!`);
// }
// return (
// <button onClick={handleClick}>
// {GroceryProps.item}
// </button>
// );
// };
export default GroceryItem;
After looking at the solutions for App.js and GroceryItem.js above, and comparing them… What I have come to realise and learn about props being passed down through the React tree (zoomed in to see its components in detail) is that they can be visualised as follows… Let us take the first GroceryItem (Eggs) as an example in this visualisation:
//<GroceryItem item="Eggs">
// imagine trying to access the Eggs value if GroceryItem was a JS object...
// Rhetorically, how might you do that?... Well, you'd type something like...
// 'GroceryItem.item' to get the value of Eggs...
// Now imagine assigning this metaphorical GroceryItem object to the name of
// another newly declared variable, namely: 'props'...
// or even clearer, something like: 'GroceryProps'...
// This same concept of the scope/access you have to certain values in a
// JS object can be applied to the scope/access a child component has to
// its parent component...
//<GroceryItem />
// Applying this to an image would look like this:
//
// **GroceryItem**
// + GroceryProps={"item"="Eggs"}
// |
// |
// V
// **button**
// + GroceryProps.item or {item}
// + ButtonProps={"onClick"="handleClick"}
//
The reason I feel this visualisation is so important to me is because I was struggling to understand that the ‘GroceryProps.item’ value was not automatically applied to the ButtonProps object… Mainly because in the exercise they refer to both the parent (GroceryItem, in this case, Eggs) and child (Button) components’ objects with the same name: ‘props’… But as a beginner, it is easier to see what is actually happening when you assign them different names specific to each component. i.e. GroceryProps & ButtonProps, to see and remind yourself that they are actually 2 completely different objects.
So while naming them the same thing (‘props’) is most likely what all advanced React developers end up doing for all their components… it is a terrible way to teach the underlying process of what is actually taking place to a beginner. @codecademy
Based on the previous exercises in this lesson (with Talker.js and Button.js, the Button function is the one that accepts props; the Talker function returns an instance of ; and it is also the Talker function which contains the event handler function handleClick) I thought that the handleClick with the alert should go within App(), and not GroceryItem().
I found the Codecademy a little buggy so had to make a local version with create-react-app to test this out. I was also struggling to get the alert to include the item that had been clicked on, but after reading through these comments I implemented an arrow function and also added an argument to the handleClick, both of which worked, so thanks to @muhamed.berdimuradov and @dylandupont !
Anyway, here is my code. As mentioned, my handleClick is in a different place to the other examples. If anyone knows whether one or the other is the more “correct” solution, or if both methods are valid, I’d love to know! Thanks!
App.js:
import React from "react";
import "./App.css";
import GroceryItem from "./GroceryItem";
function App() {
function handleClick(item) {
alert(`${item} was added to cart!`);
}
return (
<div>
<GroceryItem
name="Bread"
price="£0.50"
onClick={() => {
handleClick("Bread");
}}
/>
<GroceryItem
name="Cheese"
price="£2.00"
onClick={() => {
handleClick("Cheese");
}}
/>
</div>
);
}
export default App;
Hello, I have made my list diferentes, using an array inside of a property… It seems to work but im not sure if this is the right way to do??? Can you tell me??
my App.js:
import React from 'react';
import GroceryItem from './GroceryItem';
function App() {
return <GroceryItem name={['breadaa', 'banana', 'strawberry', 'eggs']} />
}
export default App
my GroceryItem.js:
import React from 'react';
function GroceryItem(props) {
function handleClick() {
alert('clicked');
};
/*let index = for( item in props.name) {
index = prop.name[item];
};*/
return (
<div>
<h1>hello</h1>
<button onClick={handleClick}>{props.name[0]}</button>
<button >{props.name[1]}</button>
<button >{props.name[2]}</button>
<button >{props.name[3]}</button>
</div>
);
};
export default GroceryItem;
Also in my button I have to put the index of an array to each props.name property manually. Is there a way that js my buttons just autamically take the index of an array element?? I guess I can make it with a for loop but im not sure how to do it exactly…
The map method will return a new array whose elements will be the buttons.
If for some reason, you also want the index of the elements in the array, then the map method can be given a second optional parameter as well (see documentation). Suppose you wanted to give each button an id of 'button0', 'button1' and so on. Then you could do something like:
I’m not sure what I am doing wrong here, but my buttons do not seem to be rendering… Please see below my code:
import React from 'react';
import GroceryItem from './GroceryItem';
function App() {
return (
<>
<GroceryItem name="Eggs" />
<GroceryItem name="Banana" />
<GroceryItem name="Strawberry"/>
<GroceryItem name="Bread"/>
</>
)
}
export default App;
import React from 'react';
function GroceryItem(props) {
function handleClick() {
alert({props.name} + " has been added to the basket.")
}
return <button onClick={handleClick}>{props.name}</button>
};
export default GroceryItem;
import React from 'react';
function GroceryItem(props) {
function handleClick() {
if (props.name.charAt(props.name.length - 1) === 's') {
alert(`${props.name} have been added to the cart`);
} else {
alert(`${props.name} has been added to the cart`);
}
}
return <button onClick={handleClick}>{props.name}</button>;
}
export default GroceryItem;
What I have been able to decipher is that, a lot of the time, following the examples from the lessons do NOT help!
If I had not come on this forum, I wouldn’t have ever found the solution!