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

Javascript 如何在ReactJS中处理数组对象的onClick事件?,javascript,reactjs,Javascript,Reactjs,我试图向数组中的对象添加一个onClick事件处理程序,在数组中单击的对象的类被更改,但它不是只更改一个元素的类,而是更改所有元素的类 如何使函数一次只处理一个节元素 class Tiles extends React.Component { constructor(props) { super(props); this.state = { clicked: false, content : []

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

如何使函数一次只处理一个
元素

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'))
类Tiles扩展React.Component{
建造师(道具){
超级(道具);
此.state={
点击:错,
内容:[]
};
this.onClicked=this.onClicked.bind(this);
componentDidMount(){
让url='';
let request=新请求(url{
方法:“GET”,
标题:新标题({
“内容类型”:“应用程序/json”
})
});
提取(请求)
.then(response=>response.json())
。然后(数据=>{
这是我的国家({
内容:数据
})
} );
}
onClicked(){
这是我的国家({
单击:!this.state.clicked
});
}
render(){
让tileClass=‘平铺内容’;
if(this.state.clicked){
tileClass=tileClass+“活动”
}
返回(
{this.state.pages.map((项)=>
{item.description}
)}

) } 类应用程序扩展了React.Component{ render(){ 返回( ) } } ReactDOM.render( , document.getElementById('content-app'))
这种情况正在发生,因为一旦用户单击了其中一个分区,您将为所有分区分配活动类。您需要记住用户单击的位置。因此我建议您使用数组,您将在其中存储所有单击分区的索引。在这种情况下,您的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>
  )
onClicked(数字){
let clicked=Object.assign([],this.state.clicked);
让index=clicked.indexOf(number);
如果(索引!=-1)单击。拼接(索引,1);
否则单击。推送(编号)
这是我的国家({
点击:点击
});
}
render(){
让tileClass=‘平铺内容’;
返回(
{this.state.pages.map((项,i)=>{
让tileClass=‘平铺内容’;
如果(this.state.clicked.includes(i))平铺内容+='active';
返回(
{item.description}
)
})}

)

}

这是为您而发生的,因为一旦用户单击其中一个分区,您将为所有分区分配活动类。您需要以某种方式记住用户单击的位置。因此,我建议您使用数组,您将在其中存储所有单击分区的索引。在这种情况下,您的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>
  )
onClicked(数字){
let clicked=Object.assign([],this.state.clicked);
让index=clicked.indexOf(number);
如果(索引!=-1)单击。拼接(索引,1);
否则单击。推送(编号)
这是我的国家({
点击:点击
});
}
render(){
让tileClass=‘平铺内容’;
返回(
{this.state.pages.map((项,i)=>{
让tileClass=‘平铺内容’;
如果(this.state.clicked.includes(i))平铺内容+='active';
返回(
{item.description}
)
})}

)

}

状态。页面需要跟踪各个单击状态,而不是实例范围内的单击状态

您的onClick处理程序应该接受一个索引,克隆
state.pages
,并将您的新页面状态拼接到旧页面状态所在的位置


您还可以向元素添加
数据索引
,然后选中
onClick(e){e.currentTarget.dataset.index}
,以了解哪个页面需要切换clickstate

状态。页面
需要跟踪各个单击状态,而不是实例范围内的单击状态

您的onClick处理程序应该接受一个索引,克隆
state.pages
,并将您的新页面状态拼接到旧页面状态所在的位置


您还可以将
数据索引添加到元素中,然后选中
onClick(e){e.currentTarget.dataset.index}
要知道哪个页面需要切换clickstate

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不能保证您的状态是同步更新的,因此您需要使用回调函数来保证。StackOverflow在注释中的代码工作特别差,因此这里是@Taras D中onClicked的实现anylyuk使用setState的回调版本以避免计时问题:

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不能保证您的状态是同步更新的,因此您需要使用回调函数来保证这一点。

您已经在“main content”类中单击了onclick()define。因此,这就是它激发的地方

constructor(props) {
    // super, etc., code
    this.onClicked = this.onClicked.bind(this);    // Remove this line.
}
把那部分去掉

您可以将
onClicked()
函数保留在原处。您在render()中的调用不正确,但:
onClick={this.onClicked}>
。访问onClicked属性而不是onClicked函数的,应该是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>
  )
}
render(){
让tileClass=‘平铺内容’;
返回(
//一些东西
this.onClicked()}//不要在这里调用bind。
>
{item.description}
//一些其他的东西
)
}
您已经在“主内容”类中单击了onclick()define。所以它就是在这里触发的

constructor(props) {
    // super, etc., code
    this.onClicked = this.onClicked.bind(this);    // Remove this line.
}
把那部分去掉

您可以将
onClicked()
函数保留在它所在的位置。您在render()中的调用不正确,但是:
onClick={this.onClicked}>
。它访问