At the line this.state inside constructor , I am defining the value of inStock : false .In the groupByCategory() function i am having a if( this.state.inStock ). This results in undefined. But if I add a 'this.state?.inStock' it works fine. Just trying to understand why this behaviour happens eventhough i initialized the state variable
const products = [
{ category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football" },
{ category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball" },
{ category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball" },
{ category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch" },
{ category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5" },
{ category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7" }
];
type IProps = {
}
type IState = {
query: string,
inStock: boolean,
group: {
[name: string]: IProduct[]
}
}
class FilterableProductTable extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props)
this.state = { query: '', inStock: false, group: this.groupByCategory(products) }
}
filterByName() {
const filteredList = products.filter(each => {
return each.name.startsWith(this.state.query)
})
this.groupByCategory(filteredList)
}
groupByCategory(list: IProduct[]) {
let group = list.reduce((acc: any, next) => {
const key = next.category
if (!acc[key]) acc[key] = []
if (this.state.inStock) { if (next.stocked) acc[key].push(next) }
else acc[key].push(next)
return acc
}, {})
this.setState({ group: group })
return group
}
}
CodePudding user response:
At the initialization of state variable this.state = {query: '', inStock: false, group: this.groupByCategory(products)}
groupByCategory() , this function actually uses state variable inStock
as on of the calculation needs. So when initiazling the state, this.state is obviously undefined and thats why the error.
CodePudding user response:
this.state
has not been assigned to when groupByCategory
is first called.
This is because you are calling groupByCategory
within the initial value you're assigning to this.state
Before completing this line in the constructor:
this.state = { query: '', inStock: false, group: this.groupByCategory(products) }
JS needs to figure out what will be in all of the object's properties before it completes the assignment.
So, first it attempts to resolve group
by calling groupByProperties
- at this point this.state
has not been assigned to.
You can fix this by changing the constructor like so:
constructor (props: IProps) {
super(props)
this.state = { query: '', inStock: false }
this.state.group = this.groupByCategory(products)
}
This way, this.state
and, more specifically, this.state.inStock
have been assigned before you call groupByCategory
.