Reputation: 121
I am new in react. I have a parent component Navbar, that has state "Total_Item". This array is added on click of Modal. The values are populating. Now i want to get the length of this array and show on my cart button(presently a simple button), in my Navv component. But it says undefined.
So the data is not saved in props (Tot_Item ) in the Navbar component. I am sure there is some conceptual error how react renders. A clear explanation will really help at this point.
Please see the sandbox below:
https://codesandbox.io/s/blazing-sky-cet22
Thanks sal
Upvotes: 0
Views: 808
Reputation: 11
In file Navbar.jsx
, value of this.state.Tot_Item
is empty array. Use this.setState
function to change the value of this.state.Tot_Item
=> In file Navv.jsx
value of this.props.Tot_Item
is empty array. Change the way to render an array of button.
https://codesandbox.io/s/stoic-rubin-wg2fo
Upvotes: 1
Reputation: 461
You don't need to use async
and await
in React, as it's supposed to work asynchronously. You can, however, pass a callback function to setState
to do what you want. That method shall be passed as a second parameter in your setState
call, and the function you pass will not be run until React has successfully updated the state.
this.setState({
myVar: 'value to print'
}, () => console.log(this.state.myVar));
Also, I've noticed you're calling setState
a lot of times on your listval
method. You actually don't have to call setState
multiple times if you want to set many properties at once. Since the state is an object, you can change all of the properties you want in a single call, like this:
this.setState({
Select_Price: ll,
Select_Item: ll3,
Select_Item_TotalPrice: ll6,
Total_Item: ll7
});
As for why this.props.Tot_Item
is always undefined
in your Navv
component, the reason is that a children component cannot modify its parent' state in any way.
Right now your components are structured in the following way: Navbar
contains both Navv
and Menu
. Menu
is the one that contains a list of items and is supposed to update the list of selected items, while Navv
is just supposed to display the number of items in said array.
However, there's a problem: you cannot pass data directly from Menu
to its sibling, Navv
. It's necessary to have a parent component (in this case, Navbar
) that gets the data from Menu
and pass it down to Navv
. However, it doesn't really work as you have it. The only way a children component (Menu
) can alter the parent' (Navbar
) state is by using a callback method, as seen in the example below:
Navbar
component // CHANGE: Create callback function to send data to parent
updateTotalItems = total => {
this.setState({ Total_Item: total }, () =>
console.log("total items in navbar", this.state.Total_Item)
);
};
// CHANGE: pass callback method as props to the children component that modifies the item counter
render() {
return (
<React.Fragment>
<Navv Tot_Item={this.state.Total_Item} />
<Menu
updateTotalItems={this.updateTotalItems}
Objs_Type={this.state.Category}
/>
</React.Fragment>
);
Menu
component Listval() {
/* ... */
// CHANGE: No need to call setState multiple times
this.setState(
{
Select_Price: ll,
Select_Item: ll3,
Select_Item_TotalPrice: ll6,
Total_Item: ll7
},
() => {
// CHANGE: Use callback function to send the array length to the parent component
this.props.updateTotalItems(this.state.Total_Item.length);
}
);
}
Here you have a working version of your sandbox example with all of these changes. Hope it helps!
Upvotes: 0
Reputation: 1485
You can do the below changes.
You can place your state in constructor.
You need to declare ListVal using FAT operator and setState of what you like. (In my case I have explicitly set it to 2 on click of OK button in Modal popup and its appearing on the screen too)
import React, { Component } from "react";
import Menu from "./Menu";
import Navv from "./Navv";
class Navbar extends Component {
constructor(props)
{
super(props);
this.state = {
Category: [
{
id: 1,
FoodType: "Chinese",
Menu: ["Egg Drop", "Chicken Fried", "Beef Fried"],
Price: [2, 8, 10]
},
{
id: 2,
FoodType: "Mexican",
Menu: ["Veg Burrito", "Chicken Burrito", "Beef Burrito"],
Price: [7, 8, 10]
}
],
One_Item: [
{
listvalue: null,
Select_Item: null,
Select_Price: null,
Select_Quantity: null,
Select_Item_TotalPrice: null
}
],
Total_Item: 0
};
}
Listval=async()=>{
this.setState({ Total_Item: 2});
}
render() {
return (
<React.Fragment>
<Navv Tot_Item={this.state.Total_Item} />
<Menu
Listvalll={this.Listval}
Objs_Type={this.state.Category}
/>
</React.Fragment>
);
}
}
export default Navbar;
Upvotes: 0