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

React Hooks多Checkbox状态异常:点击单个触发全部状态变更

解决React Hooks中多个Checkbox状态同步问题及警告处理

嘿,我看到你遇到了两个头疼的问题:多个Checkbox点一个全变,还有两个React警告。咱们一步步来把它们搞定:

核心问题:所有Checkbox共用同一个状态变量

你现在用单个checked布尔值管理所有Checkbox的状态,这就像把所有开关连在同一个电源上,碰一个全亮全灭。解决方法很简单——给每个设备维护独立的状态,用对象来存储每个设备id对应的开关状态。

修改后的完整代码

import React,{useState} from 'react';
import { Box, Checkbox, Flex, Table, Txt } from 'rendition';
import styled from 'styled-components';

const ControlContainer = styled(Box)`
 border-top-left-radius: 10px;
`;

export const Devices = () => {
  // 初始化状态:用对象存储每个设备id对应的开关状态
  const [checkedStates, setCheckedStates] = useState(
    SAMPLE_DATA.reduce((acc, item) => {
      acc[item.id] = item.active;
      return acc;
    }, {})
  );

  // 切换函数:根据设备id更新对应状态
  const toggle = (id) => {
    setCheckedStates(prevStates => ({
      ...prevStates,
      [id]: !prevStates[id]
    }));
  };

  const SAMPLE_DATA = [
    { id: 1, name: 'Balcony', active: true, brightness: 50, },
    { id: 2, name: 'Bedroom 01', active: false, brightness: 70, },
    { id: 3, name: 'Bedroom 02', active: false, brightness: 70, },
  ];

  const columns = [
    { field: 'name', label: 'Room', sortable: true, },
    { 
      field: 'active', 
      label: 'State', 
      sortable: true,
      // 接收当前行的value和row数据
      render(value, row) {
        const isChecked = checkedStates[row.id];
        return (
          // 加上唯一key解决第一个警告
          <Flex key={row.id}>
            <Checkbox 
              toggle 
              checked={isChecked} 
              // 绑定toggle时传入当前行的id
              onChange={() => toggle(row.id)} 
              mr={2} 
            />
            <Txt ml={2}>{isChecked ? 'On' : 'Off'}</Txt>
          </Flex>
        );
      },
    },
    { 
      field: 'brightness', 
      label: 'Brightness', 
      sortable: true,
      render(value) {
        return `${value}%`;
      },
    },
  ];

  return (
    <Flex flex='1' mt={4}>
      <Box flex='3' pl={3}>
        <Table flex='1' columns={columns} data={SAMPLE_DATA} rowKey='id' onRowClick={console.log} />
      </Box>
    </Flex>
  );
};

警告问题逐个拆解解决

1. Each child in a list should have a unique key prop.

这个警告是React在提醒你:渲染列表时每个子元素需要唯一标识,这样它才能准确追踪元素的变化。我们在active列的render函数里,给返回的<Flex>组件加上了key={row.id}——用设备的唯一id作为key,完美解决这个问题。

2. Failed prop type: You provided a checked prop to a form field without an onChange handler.

原来的toggle函数写法有bug(嵌套调用setChecked),而且没有给每个Checkbox绑定专属的状态更新逻辑。现在我们修改了toggle函数,让它接收设备id,并且在每个Checkbox的onChange里传入当前行的id,确保每个Checkbox都有对应的状态更新逻辑,同时checked状态和onChange正确关联,这个警告自然就消失了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:25