使用for循环对列表中的项目进行反应 - onClick(项目)

Raf*_*ues 0 javascript onclick reactjs redux

我正在制作一个反应列表,其项目应触发更新状态的操作.然而,触发和状态更新都会发生,而onClick方法每次都使用相同的参数调用该操作.这不应该发生.传递给操作的参数必须取决于单击列表的项目.

我无法找到导致此错误的错误.

这是我的下拉类,其中呈现列表.

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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

这是管理状态并调用上述类的容器

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)
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

我用catName的控制台日志替换了this.props.onClick,它总是记录相同的,但是它正确地显示了

标签.

Pra*_*rma 7

你的for循环不会形成closure.更好地使用这样的地图功能

let content = categories.map((catName, i) => {
      return (
        <li
          key ={i}
          onClick = {() => {this.props.onClick(catName)}}
        >
        <p>{catName}</p>
        </li>
      )
    });
Run Code Online (Sandbox Code Playgroud)

  • 只是一个简短的评论:使用索引作为键并不是_总是_一个坏主意。如果保证列表中的项目不会改变它们的顺序,那么使用索引就可以了。否则,您将需要为每个被映射的记录使用唯一标识符。 (2认同)