You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React实现每行单个Div单选(类似单选按钮)功能

实现React中每行仅单个Div选中的功能

嘿,作为React新手碰到这种需求完全没问题,我来一步步带你实现这个功能,核心思路是用React的状态来跟踪每行的选中项,然后动态切换样式类~

步骤1:用useState管理选中状态

我们需要一个状态来记录每一行当前选中的Div下标,比如用一个对象,键是行的标识(比如row1、row2),值是选中的Div索引(0、1、2)。初始化的时候对应你静态代码里默认选中第一个Div的情况。

步骤2:编写点击事件处理函数

当点击某一行里的Div时,我们只更新对应行的选中状态,不会影响其他行的选中结果。

步骤3:动态绑定className

根据当前行的选中状态,给对应的Div加上select类,其他Div则不加。


完整代码示例(函数组件)

import { useState } from 'react';

function SelectableRows() {
  // 初始化状态:每行默认选中第一个Div(索引0)
  const [selectedItems, setSelectedItems] = useState({
    row1: 0,
    row2: 0,
    row3: 0
  });

  // 处理选中事件:接收行标识和当前Div的索引
  const handleSelect = (rowKey, index) => {
    // 用函数式更新确保拿到最新的状态
    setSelectedItems(prevState => ({
      ...prevState,
      [rowKey]: index
    }));
  };

  return (
    <div>
      {/* 第一行 */}
      <div className="row">
        <div 
          className={`heil ${selectedItems.row1 === 0 ? 'select' : ''}`}
          onClick={() => handleSelect('row1', 0)}
        >
          <button>Click One</button>
        </div>
        <div 
          className={`heil ${selectedItems.row1 === 1 ? 'select' : ''}`}
          onClick={() => handleSelect('row1', 1)}
        >
          <button>Click Two</button>
        </div>
        <div 
          className={`heil ${selectedItems.row1 === 2 ? 'select' : ''}`}
          onClick={() => handleSelect('row1', 2)}
        >
          <button>Click Three</button>
        </div>
      </div>

      {/* 第二行 */}
      <div className="row">
        <div 
          className={`heil ${selectedItems.row2 === 0 ? 'select' : ''}`}
          onClick={() => handleSelect('row2', 0)}
        >
          <button>Click One</button>
        </div>
        <div 
          className={`heil ${selectedItems.row2 === 1 ? 'select' : ''}`}
          onClick={() => handleSelect('row2', 1)}
        >
          <button>Click Two</button>
        </div>
        <div 
          className={`heil ${selectedItems.row2 === 2 ? 'select' : ''}`}
          onClick={() => handleSelect('row2', 2)}
        >
          <button>Click Three</button>
        </div>
      </div>

      {/* 第三行 */}
      <div className="row">
        <div 
          className={`heil ${selectedItems.row3 === 0 ? 'select' : ''}`}
          onClick={() => handleSelect('row3', 0)}
        >
          <button>Click One</button>
        </div>
        <div 
          className={`heil ${selectedItems.row3 === 1 ? 'select' : ''}`}
          onClick={() => handleSelect('row3', 1)}
        >
          <button>Click Two</button>
        </div>
        <div 
          className={`heil ${selectedItems.row3 === 2 ? 'select' : ''}`}
          onClick={() => handleSelect('row3', 2)}
        >
          <button>Click Three</button>
        </div>
      </div>
    </div>
  );
}

export default SelectableRows;

优化:用循环简化代码

如果你的行数量比较多,或者以后可能扩展,用循环生成行和Div会更简洁,比如:

import { useState } from 'react';

function SelectableRows() {
  // 假设有3行,每行3个选项
  const rowCount = 3;
  const itemCountPerRow = 3;

  // 初始化状态,每行默认选中索引0
  const initialState = {};
  for (let i = 1; i <= rowCount; i++) {
    initialState[`row${i}`] = 0;
  }
  const [selectedItems, setSelectedItems] = useState(initialState);

  const handleSelect = (rowKey, index) => {
    setSelectedItems(prev => ({ ...prev, [rowKey]: index }));
  };

  return (
    <div>
      {Array.from({ length: rowCount }).map((_, rowIndex) => {
        const rowKey = `row${rowIndex + 1}`;
        return (
          <div key={rowKey} className="row">
            {Array.from({ length: itemCountPerRow }).map((_, itemIndex) => (
              <div
                key={itemIndex}
                className={`heil ${selectedItems[rowKey] === itemIndex ? 'select' : ''}`}
                onClick={() => handleSelect(rowKey, itemIndex)}
              >
                <button>Click {['One', 'Two', 'Three'][itemIndex]}</button>
              </div>
            ))}
          </div>
        );
      })}
    </div>
  );
}

export default SelectableRows;

关键知识点解释

  • 状态管理:用对象类型的状态来区分不同行的选中状态,保证每行的选中操作互不干扰。
  • 函数式更新:setSelectedItems(prev => {...})这种写法可以确保我们基于最新的状态进行更新,避免状态更新的异步问题。
  • 动态className:用模板字符串判断当前Div是否是该行的选中项,从而动态添加select类,实现高亮效果。

这样就能完美实现你要的“每行仅能选中一个Div,切换时取消之前选中状态”的功能啦~

内容的提问来源于stack exchange,提问作者manoop m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:32:28