Reputation: 1445
I am making a react list, whose items should trigger an action to update state. Both the triggering and the state update occur, however, the onClick method is calling the action with the same argument every time. This should not occur. The argument passed to the action must depend on the item of the list clicked.
I can not seam to find the bug that is causing this error.
This is my dropdown class, where the list is rendered.
class DropDownMenu extends React.Component {
constructor(props){
super(props)
}
render(){
let content = []
var categories = this.props.categories
for (var i=0; i < categories.length; i++) {
var catName = categories[i]
var line = (
<li
key ={i}
onClick = {() => {this.props.onClick(catName)}}
>
<p>{catName}</p>
</li>
)
content.push(line)
}
return (
<div>
<Dropdown ref="dropdown">
<DropdownTrigger>Categories</DropdownTrigger>
<DropdownContent>
<ul>
{ content }
</ul>
</DropdownContent>
</Dropdown>
</div>
)
}
}
This is the container that manages the state and calls the above class
class MenuContainer extends React.Component {
constructor(props) {
super(props)
}
render(){
return (
<div>
<div>
<a onClick = {() => {this.props.changeView("main")}}>back</a>
<a onClick = {() => {this.props.changeView("shoppingCart ")}}>my cart</a>
</div>
<div>
<DropDownMenu
categories = {this.props.categories}
onClick = {(catName) => {this.props.selectCategory(catName)}}
/>
<ItemList
items = {this.props.items}
/>
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
categories: getCategories(state),
items: getItems(state)
}
}
const mapDispathToProps = (dispatch) => {
return {
changeView: (view) => {
dispatch(setView(view))
},
selectCategory: (catName) => {
dispatch(setCategory(catName))
}
}
}
export default connect(mapStateToProps, mapDispathToProps)(MenuContainer)
I reducer the error to the line:
for (var i=0; i < categories.length; i++) {
var catName = categories[i]
var line = (
<li
key ={i}
onClick = {() => {this.props.onClick(catName)}}
>
<p>{catName}</p>
I replaced this.props.onClick with console log of the catName, and it always logs the same, althoug it correctly shows the items in the
tag.
Upvotes: 0
Views: 6420
Reputation: 16472
Your for
loop does not form a closure
. Better use a map function like this
let content = categories.map((catName, i) => {
return (
<li
key ={i}
onClick = {() => {this.props.onClick(catName)}}
>
<p>{catName}</p>
</li>
)
});
Upvotes: 7