【问题标题】:React - Loop through an array of objects, and highlight the selected item onClickReact - 循环遍历对象数组,并在单击时突出显示所选项目
【发布时间】:2018-05-24 19:11:36
【问题描述】:

我有一个包含数据的对象数组,我使用 map 将其输出到 DOM。列表中的每个项目都有一个 onClick 事件侦听器。当您单击其中一个项目时,我希望通过添加一个 css 类来突出显示它,例如“悬停”。所以基本上它应该像菜单系统一样工作。当您单击一个项目时,该项目会突出显示,而其他项目不应突出显示,反之亦然。

按照我现在的设置方式,列表中的所有项目都会突出显示,这不是我想要做的逻辑。我使用了 console.log 来显示已单击的项目。但是,我仍然没有弄清楚,如何使选定的项目成为突出显示而不是整个列表的项目?

import React, { Component } from 'react';

class MenuSelector extends Component {
    state = {
        active: false,
        menu: [
            {
                id: 1,
                fighterName: 'Goku',
                race: 'Sayian',
                specialAttack: 'Kamehameha Wave',
                img: 'https://nerdist.com/wp-content/uploads/2018/01/Dragon-Ball-Super-Goku.jpg'
            },
            {
                id: 2,
                fighterName: 'Vegeta',
                race: 'Sayian',
                specialAttack: 'Final Flash',
                img: 'https://imgmr.com/wp-content/uploads/2016/04/Vegeta-SSGSS-2.png'
            },
            {
                id: 3,
                fighterName: 'Gohun',
                race: 'Human',
                specialAttack: 'Masenko',
                img: 'https://techanimate.com/wp-content/uploads/2017/11/Why-does-Gohan-Have-so-much-Hidden-Power-1024x576.jpg'
            },
            {
                id: 4,
                fighterName: 'Krillin',
                race: 'Human',
                specialAttack: 'Destructo Disc',
                img: 'https://static3.srcdn.com/wordpress/wp-content/uploads/2016/09/Krillin-Destructo-Disk.jpg'
            },
            {
                id: 5,
                fighterName: 'Android 17',
                race: 'Android',
                specialAttack: 'Barrier',
                img: 'https://i.ytimg.com/vi/SzAiIy_Dnb4/maxresdefault.jpg'
            },
            {
                id: 6,
                fighterName: 'Jiren',
                race: 'Unknown',
                specialAttack: 'Eye Paralysis',
                img: 'https://vignette.wikia.nocookie.net/dragonuniverse/images/9/9c/Jiren.png/revision/latest/scale-to-width-down/2000?cb=20180211002429'
            },
            {
                id: 7,
                fighterName: 'Lord Beerus',
                race: 'God',
                specialAttack: 'Hakai',
                img: 'https://vignette.wikia.nocookie.net/dragonuniverse/images/3/30/Beerus2.png/revision/latest?cb=20170225064338'
            },
            {
                id: 8,
                fighterName: 'Cell',
                race: 'Android',
                specialAttack: 'Kamehameha Wave',
                img: 'https://static0.srcdn.com/wordpress/wp-content/uploads/Dragon-Ball-Z-Perfect-Cell.jpg'
            },
            {
                id: 9,
                fighterName: 'Frieza',
                race: 'Unknown',
                specialAttack: 'Finger Blasters',
                img: 'https://i.ytimg.com/vi/BkoOw_7JqKg/maxresdefault.jpg'
            },
            {
                id: 10,
                fighterName: 'Black Goku',
                race: 'Sayian',
                specialAttack: 'Ki Blade',
                img: 'https://pm1.narvii.com/6287/eafbdf4dc0ae1b58d3869b89be04bcd0712f7623_hq.jpg'
            },
        ]
    }
    toggleClass = (id) => {
        console.log(`Clicked item ${id}`, this);

        const currentState = this.state.active;
        this.setState({ active: !currentState });
    };

    selectHandler = (id) => {
        console.log(`Clicked item ${id}`);
        console.log(this);

    }

  render() {
    return (
      <div className="container">
        <h1>Menu Selector</h1>
        <div>
        <ul>
            {this.state.menu.map((dragonball, index) => (
                <li key={index} onClick={() => this.toggleClass(dragonball.id)} className={this.state.active ? 'hover': null}>
                <div className="container-dragonball">
                <div className="dragonball-stats">
                <h1>{dragonball.fighterName}</h1>
                <p>Race: {dragonball.race}</p>
                <p>Special Attack: {dragonball.specialAttack}</p>
                </div>
                <div className="dragonball-img"><img src={dragonball.img} alt={dragonball.fighterName} /></div>
                </div>
                </li>
            ))}
            </ul>
        </div>
      </div>
    );
  }
}

export default MenuSelector;

【问题讨论】:

    标签: javascript arrays reactjs object


    【解决方案1】:

    更新了toggleClass 以将selected item id 添加到状态。

    toggleClass = (id) => {
    
            this.setState({ selectedItemIndex: id });
        };
    

    现在, 用

    修改了li

    className={this.state.selectedItemIndex== dragonball.id? 'hover': null}.

    循环menu 并检查selected item id。如果 id 匹配,则添加所需的类

        <li key={index} onClick={() => this.toggleClass(dragonball.id)} 
    className={this.state.selectedItemIndex== dragonball.id? 'hover': null}>
    

    【讨论】:

    • 感谢您提供的解决方案有效。就一件事。我认为它应该是“===”而不是“==”。当我遵守它时,它被标记为错误。所以下面的修改代码可能更理想。
    • this.toggleClass(dragonball.id)} className={this.state.selectedItemIndex === dragonball.id ? '悬停': null}>
  • 抱歉,我的错。=== 更好,但请确保响应的数据类型一致
  • @AndrewBaisden 如果工作正常,请接受并投票。
  • 【解决方案2】:

    这样可以多选

     handleSelect = ( id) => {
        const selection = this.state.selected
        if (this.state.selected[id] == 1) {
          selection[id] = 0 //deselect the item
        } else selection[id] = 1 //select the item
        this.setState({ selected: selection }, () =>
          console.log(this.state.selected)
        )
      }
    

    然后像这样添加你的类名

    <li className={ ` ${this.state.selected[dragonball.id] == 1 && "selected"}` }>
    

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签