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
相关产品推荐
相关产品推荐

