每个元素共享相同的状态,而不是自己的状态

时间:2018-07-22 08:52:09

标签: reactjs jsx

我是React的新手,我正在尝试创建一个简单的投票应用程序,该应用程序具有一个项目列表,每个项目都有很多票和一个用于增加该特定项目的投票的按钮。

我遇到的问题是,将同时更新所有项目的投票,而不是该特定项目的投票。似乎每个项目都成功拥有自己的唯一密钥,但是我不明白为什么我不能单挑那个特定的项目来增加其票数。

我尝试创建一个单独的函数来运行this.props.items.map(),但我也没有运气。

到目前为止,我的代码:

    <script src="node_modules/react/umd/react.development.js"></script>
    <script src="node_modules/react-dom/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <div id="root"></div>

    <script type="text/babel">
        class List extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    votes: 0,
                }
                this.handleClick = this.handleClick.bind(this);
            }

        handleClick(event) {
            const votes = this.state.votes;
            this.setState({
                votes: votes + 1
            })
        }

        render() {
            return (
                <div>
                    <h1>Vote Your JS Library!</h1>
                    <ul>
                        { this.props.items.map((item) => 
                            <li key = {item}>
                                {this.state.votes}
                                {item}
                                <button onClick = { () => this.handleClick() }> + </button>
                            </li>
                        ) }
                    </ul>
                </div>
            )
        }
    }

    ReactDOM.render(<List items= { ['React', 'Vue', 'Angular', 'Ember'] } />, document.getElementById('root'));
</script>

5 个答案:

答案 0 :(得分:0)

每个列表项都需要具有自己的状态

if (Build.VERSION.SDK_INT < 26 || getSystemService<PowerManager>()
        ?.isIgnoringBatteryOptimizations(packageName) != false) {
    startService(Intent(context, MyService::class.java))
} // else calling startService will result in crash

为简单起见,为每个列表项创建一个事件处理程序。如果有机会,一旦有了这些工作,您就可以运用DRY的原理(不再重复)。否则,请稍等一下,毕竟您才刚刚开始使用React。

答案 1 :(得分:0)

这应该有效。

1*10000+ 2 * 1000 + 3*100 + 4*10 + 5

答案 2 :(得分:0)

您的投票状态适用于列表组件,而不适用于每个ListItem。

您可以通过创建一个名为ListItem的新组件来解决该问题,该组件将接收名称作为道具,并且可以在此组件中定义将针对每个项目的投票状态。还要在此组件中移动handleClick函数。

`class ListItem extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
       votes: 0,
     }
     this.handleClick = this.handleClick.bind(this);
   }

   handleClick(event) {
     const votes = this.state.votes;
     this.setState({
       votes: votes + 1
     })
   }
   render() {
     return <li>
       {this.state.votes}
       {item}
       <button onClick = { () => this.handleClick() }> + </button>
     </li>
   }
}

`

或者您可以像这样管理当前列表组件中的状态散列。

class List extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                votes: {},
            }
            this.items = [];
            this.handleClick = this.handleClick.bind(this);
        }

    handleClick(item) {
        const votes = this.state.votes;
        votes[item] = (votes[item] || 0) + 1;
        this.setState({
            votes: votes
        })
    }

    render() {
        return (
            <div>
                <h1>Vote Your JS Library!</h1>
                <ul>
                    { this.props.items.map((item) => 
                        <li key = {item}>
                            {this.state.votes[item] || 0}
                            {item}
                            <button onClick = { () => this.handleClick(item) }> + </button>
                        </li>
                    ) }
                </ul>
            </div>
        )
    }
}

答案 3 :(得分:0)

您正在使用一个表决变量并将其呈现给所有项目,因此这就是为什么您对所有项目都得到相同的结果的原因,因此请尝试这样做:

工作示例https://codesandbox.io/s/7ym8606pm0

import React from 'react';
import ReactDOM from 'react-dom'
class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      votes: [0, 0, 0, 0],
    }
    this.items = [];
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(i) {
    const newVotes = [...this.state.votes];
    newVotes[i] = newVotes[i] + 1;
    this.setState({
      votes: newVotes
    })
  }

  render() {
    return (
      <div>
        <h1>Vote Your JS Library!</h1>
        <ul>
          {this.props.items.map((item, index) =>
            <li key={item}>
              {this.state.votes[index]}
              {item}
              <button onClick={() => this.handleClick(index)}> + </button>
            </li>
          )}
        </ul>
      </div>
    )
  }
}

ReactDOM.render(<List items={['React', 'Vue', 'Angular', 'Ember']} />, document.getElementById('root'));

答案 4 :(得分:0)

您没有为每个项目存储this.state.votes,而是为所有项目存储。

需要更改数据结构。

<List  items = {

'React' : { votes: 0},
'Vue'  :  { votes: 0},
'Angular'  : { votes: 0},
'Ember'  : { votes: 0}
} />

构造函数:

constructor(props) {
    ....
    this.state.items = this.props.items;
    ...
}

渲染:

<ul>
  {this
    .state
    .items
    .map((item,name) => <li key={name}>
      {item.votes}
      {name}
      <button onClick= { () => this.handleClick(name) }>
        +
      </button>
    </li>)}
</ul>

handleClick

handleClick=(name)=> {

    let  updatedItems = { [name] : parseInt(this.state.items[key].votes) + 1 };

    this.setState({
        item: [...this.state.items,...updatedItems]
    })
}