admin管理员组

文章数量:1400762

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>
    )
  }
}

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.

Share Improve this question edited Nov 20, 2017 at 18:21 Rafael Marques asked Nov 20, 2017 at 18:09 Rafael MarquesRafael Marques 1,4455 gold badges26 silver badges38 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

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>
      )
    });

本文标签: javascriptReactonClick(item) of item in list using for loopStack Overflow