【问题标题】:Add "active" class attribute to clicked item in React在 React 中为单击的项目添加“活动”类属性
【发布时间】:2018-03-28 17:45:21
【问题描述】:

我只想在单击的项目上添加“活动”类属性。到目前为止,我有一个名为 activeItem 的状态属性:

constructor(props) {
    super(props);
    this.state = { clickedNotebookId: '', activeItem: false };
}

我在 click 函数中将状态更改为 true:

renderContent(event) {
    this.setState({clickedNotebookId: this.props.id, activeItem: true}, function(){
        //display content
    });
}

在我的 render() 方法中,我执行以下操作:

<div className="list-group">
    <a href="#" className={this.state.activeItem == true ? 'list-group-item active' : 'list-group-item'} onClick={this.renderContent}>{this.props.title}
    <button className="pull-right btn btn-xs btn-danger" type="button" onClick={this.deleteNotebook}>
        <strong>x</strong>
    </button>
    </a>
</div>

-

className={this.state.activeItem == true ? 'list-group-item active' : 'list-group-item'}

我知道上面的条件是错误的,因为它在单击时会激活所有项目。理想情况下,它应该只突出显示单击的项目。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您应该检查正在激活的项目的id,或者以更“反应性”的方式进行检查,并将其作为组件,使用像idisActive 这样的道具。
    当点击时,子节点会将子节点的id向上传递给父节点,这将允许父节点在状态中存储当前活动的id。
    当父级将使用循环重新渲染子项时,它将检查当前活动项 id 是否等于当前迭代中当前项的 id。如果是这样,那么它会将孩子的isActive 属性作为true 传递。
    孩子有责任相应地呈现自己。

    例子:

    const items = [1, 2, 3, 4, 5];
    
    class MyItem extends React.Component {
      renderContent = e => {
        const { itemId, renderContent } = this.props;
        renderContent(itemId);
      };
    
      deleteNotebook = e => {
        const { itemId, deleteNotebook } = this.props;
        deleteNotebook(itemId);
      };
    
      render() {
        const { isActive } = this.props;
        const groupItemClass = `list-group-item ${isActive && "active"}`;
        return (
          <div className="list-group">
            <a href="#" className={groupItemClass} onClick={this.renderContent}>
              {this.props.title}
              <button
                className="pull-right btn btn-xs btn-danger"
                type="button"
                onClick={this.deleteNotebook}
              >
                <strong>x</strong>
              </button>
            </a>
          </div>
        );
      }
    }
    
    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
    
      renderContent = id => {
        console.clear();
        console.log(`rendering content for item id - ${id}`);
        this.setState({ activeItem: id });
      };
    
      deleteNotebook = id => {
        // do something..
      };
    
      render() {
        const { activeItem } = this.state;
        return (
          <div>
            {
              items.map((item) => <MyItem renderContent={this.renderContent} deleteNotebook={this.deleteNotebook} itemId={item} isActive={activeItem === item} />)
            }
          </div>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    【讨论】:

    • 我很难理解这一点。你能解释一下反应较少的方法吗?
    【解决方案2】:

    activeItem 属性有点“全局”,这意味着它与特定项目无关。当发生 Click 事件时,“全局”属性 activeItem 更改为 true,这意味着对于您检查 activeItem 的每个项目,所有项目都将是 true。因此,所有项目都会突出显示。

    因此,您必须为每个项目创建单独的组件并管理本地状态

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      • 2019-07-07
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多