如何在ReactJS中处理数组对象的onClick事件?

时间:2017-10-31 21:59:24

标签: javascript reactjs

我正在尝试向数组中的对象添加onClick事件处理程序,其中更改了单击对象的类,但它不是仅更改一个元素的类,而是更改所有类的类元素。

如何让函数一次仅处理一个section元素?

class Tiles extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            clicked: false,
            content : []
        };
    this.onClicked = this.onClicked.bind(this);

componentDidMount() {
    let url = '';
    let request = new Request(url, {
        method: 'GET',
        headers: new Headers({
            'Content-Type': 'application/json'
        })
    });
    fetch(request)
    .then(response => response.json())
    .then(data => {
        this.setState({
            content : data
        })
    } );

}

onClicked() {
    this.setState({
        clicked: !this.state.clicked
        });
}

render() {
    let tileClass = 'tile-content';
    if (this.state.clicked) {
        tileClass = tileClass + ' active'
    }
    return (
    <div className = 'main-content'>
    {this.state.pages.map((item) => 
        <section key = {item.id} className = {tileClass} onClick = {this.onClicked}>
        <h4>{item.description}</h4>
        </section>)}
        <br />
    </div>
    )
 }

class App extends React.Component {
    render() {
       return (
        <div>
            <Tiles />
        </div>
       )
 }
}

ReactDOM.render(
     <App />,
    document.getElementById('content-app'))

4 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为一旦用户点击其中一个部分,您就会将活动类分配给所有部分。你需要以某种方式记住用户点击的位置。所以我建议你使用数组,你将存储所有点击部分的索引。在这种情况下,你的state.clicked现在是一个数组。

onClicked(number) {
  let clicked = Object.assign([], this.state.clicked);
  let index = clicked.indexOf(number);
  if(index !== -1) clicked.splice(index, 1);
  else clicked.push(number)
  this.setState({
    clicked: clicked
  });
}

render() {
  let tileClass = 'tile-content';
  return (
    <div className = 'main-content'>
      {this.state.pages.map((item, i) => { 
        let tileClass = 'tile-content';
        if(this.state.clicked.includes(i)) tile-content += ' active';
        return (
          <section key = {item.id} className = {tileClass} onClick = {this.onClicked.bind(this, i)}>
            <h4>{item.description}</h4>
          </section>
        )
      })}
      <br />
    </div>
  )

}

答案 1 :(得分:0)

state.pages需要跟踪单个点击状态,而不是实例范围内的点击状态

你的onClick处理程序应该接受一个索引,克隆state.pages并拼接新的页面状态,过时的那个曾经是

您还可以在元素中添加data-index,然后检查onClick (e) { e.currentTarget.dataset.index }以了解哪个页面需要切换clickstate

答案 2 :(得分:0)

StackOverflow在评论中的代码工作特别糟糕,所以这里是使用setState的回调版本从@Taras Danylyuk实现onClicked以避免时间问题:

onClicked(number) {
  this.setState((oldState) => {
    let clicked = Object.assign([], this.state.clicked);
    let index = clicked.indexOf(number);
    if(index !== -1) {
      clicked.splice(index, 1);
    } else {
      clicked.push(number);
    }
    return { clicked };
  });
}

您需要这个的原因是因为您正在根据旧状态修改新状态。 React不保证您的状态是同步更新的,因此您需要使用回调函数来进行保证。

答案 3 :(得分:0)

你的'main-content'类中有onClicked()定义。这就是它发射的地方。

constructor(props) {
    // super, etc., code
    this.onClicked = this.onClicked.bind(this);    // Remove this line.
}

删除该部分。

您可以将onClicked()功能保持在原位。但是,您在render()中的调用不正确:onClick = {this.onClicked}>。它访问onClicked ATTRIBUTE ,而不是onClicked FUNCTION ,它应该是this.onClicked()。

让我在render()稍微清理你的电话:

render() {
  let tileClass = 'tile-content';
  return (
    <div className = 'main-content'>
          // some stuff
          <section
               key={item.id}
               className={tileClass}
               onClick={() => this.onClicked()}        // Don't call bind here.
          >
            <h4>{item.description}</h4>
          </section>
          // some other stuff
    </div>
  )
}