Missing "key" prop for element in iterator
55 const disksData = matchFileSystemAndSmart(healthInfo.fileSystem, healthInfo.smart);
56
57 return (
58 <Box> 59 <Card m="2.5cqmin" p="2.5cqmin" withBorder> 60 <Flex justify="space-between" align="center" key={integrationId}> 61 <HoverCard> 62 <HoverCard.Target> 63 <Indicator 64 inline 65 processing 66 color={healthInfo.rebootRequired ? "red" : healthInfo.availablePkgUpdates > 0 ? "blue" : "gray"} 67 position="top-end" 68 size={12} 69 label={healthInfo.availablePkgUpdates > 0 ? healthInfo.availablePkgUpdates : undefined} 70 disabled={!healthInfo.rebootRequired && healthInfo.availablePkgUpdates === 0} 71 > 72 <Avatar size="md" radius="sm"> 73 <IconInfoSquare size={32} /> 74 </Avatar> 75 </Indicator> 76 </HoverCard.Target> 77 <HoverCard.Dropdown> 78 <List center spacing="0.5cqmin"> 79 <List.Item icon={<IconCpu2 size={16} />}> 80 {t("widget.healthMonitoring.popover.model")}: {healthInfo.cpuModelName} 81 </List.Item> 82 <List.Item icon={<IconVersions size={16} />}> 83 {t("widget.healthMonitoring.popover.version")}: {healthInfo.version} 84 </List.Item> 85 <List.Item icon={<IconClock size={16} />}> 86 {t("widget.healthMonitoring.popover.uptime")}: {formatUptime(healthInfo.uptime)} 87 </List.Item> 88 </List> 89 </HoverCard.Dropdown> 90 </HoverCard> 91 {options.cpu && ( 92 <RingProgress 93 roundCaps 94 size={100} 95 thickness={12} 96 label={ 97 <Center style={{ flexDirection: "column" }}> 98 <Text size="3cqmin">{`${healthInfo.cpuUtilization.toFixed(2)}%`}</Text> 99 <HoverCard>100 <HoverCard.Target>101 <IconCpu size={25} />102 </HoverCard.Target>103 <HoverCard.Dropdown>104 <List center spacing="0.5cqmin" icon={<IconCpu2 size={16} />}>105 <Text fw={700} td="underline">106 {t("widget.healthMonitoring.popover.loadAverage")}107 </Text>108 <List.Item>109 1 {t("widget.healthMonitoring.popover.minute")}: {healthInfo.loadAverage["1min"]}110 </List.Item>111 <List.Item>112 5 {t("widget.healthMonitoring.popover.minutes")}: {healthInfo.loadAverage["5min"]}113 </List.Item>114 <List.Item>115 15 {t("widget.healthMonitoring.popover.minutes")}: {healthInfo.loadAverage["15min"]}116 </List.Item>117 </List>118 </HoverCard.Dropdown>119 </HoverCard>120 </Center>121 }122 sections={[123 {124 value: Number(healthInfo.cpuUtilization.toFixed(2)),125 color: progressColor(Number(healthInfo.cpuUtilization.toFixed(2))),126 },127 ]}128 />129 )}130 {healthInfo.cpuTemp && options.cpu && (131 <RingProgress132 roundCaps133 size={100}134 thickness={12}135 label={136 <Center style={{ flexDirection: "column" }}>137 <Text size="3cqmin">138 {options.fahrenheit139 ? `${(healthInfo.cpuTemp * 1.8 + 32).toFixed(1)}°F`140 : `${healthInfo.cpuTemp}°C`}141 </Text>142 <IconCpu size={25} />143 </Center>144 }145 sections={[146 {147 value: healthInfo.cpuTemp,148 color: progressColor(healthInfo.cpuTemp),149 },150 ]}151 />152 )}153 {options.memory && (154 <RingProgress155 roundCaps156 size={100}157 thickness={12}158 label={159 <Center style={{ flexDirection: "column" }}>160 <Text size="3cqmin">{memoryUsage.memUsed.GB}GiB</Text>161 <HoverCard>162 <HoverCard.Target>163 <IconBrain size={25} />164 </HoverCard.Target>165 <HoverCard.Dropdown>166 <List center spacing="0.5cqmin" icon={<IconBrain size={16} />}>167 <List.Item>168 {t("widget.healthMonitoring.popover.total")}: {memoryUsage.memTotal.GB}GiB169 </List.Item>170 <List.Item>171 {t("widget.healthMonitoring.popover.available")}: {memoryUsage.memFree.GB}GiB (172 {memoryUsage.memFree.percent}%)173 </List.Item>174 </List>175 </HoverCard.Dropdown>176 </HoverCard>177 </Center>178 }179 sections={[180 {181 value: Number(memoryUsage.memUsed.percent),182 color: progressColor(Number(memoryUsage.memUsed.percent)),183 tooltip: `${memoryUsage.memUsed.percent}%`,184 },185 ]}186 />187 )}188 </Flex>189 </Card>190 {options.fileSystem &&191 disksData.map((disk) => {192 return (193 <Card key={disk.deviceName} m="2.5cqmin" p="2.5cqmin" withBorder>194 <Flex justify="space-between" align="center" m="1.5cqmin">195 <Group gap="1cqmin">196 <IconServer size={18} />197 {disk.deviceName}198 </Group>199 <Group gap="1cqmin">200 <IconTemperature size={18} />{" "}201 {options.fahrenheit ? `${(disk.temperature * 1.8 + 32).toFixed(1)}°F` : `${disk.temperature}°C`}202 </Group>203 <Group gap="1cqmin">204 <IconFileReport size={18} />205 {disk.overallStatus}206 </Group>207 </Flex>208 <Progress.Root size={20}>209 <Tooltip label={disk.used}>210 <Progress.Section value={disk.percentage} color={progressColor(disk.percentage)}>211 <Progress.Label>{t("widget.healthMonitoring.popover.used")}</Progress.Label>212 </Progress.Section>213 </Tooltip>214215 <Tooltip216 label={217 Number(disk.available) / 1024 ** 4 >= 1218 ? `${(Number(disk.available) / 1024 ** 4).toFixed(2)} TiB`219 : `${(Number(disk.available) / 1024 ** 3).toFixed(2)} GiB`220 }221 >222 <Progress.Section value={100 - disk.percentage} color="default">223 <Progress.Label>{t("widget.healthMonitoring.popover.available")}</Progress.Label>224 </Progress.Section>225 </Tooltip>226 </Progress.Root>227 </Card>228 );229 })}230 </Box>231 );
232 })}
233 </Box>
Description
A key
is a special string attribute you need to include when creating lists of elements because keys help React
identify which items have changed, added, or removed.
Keys should be given to the elements to give them a stable identity.
The best way to pick a key
is to use a string that uniquely identifies a list item among its siblings. Most often, you would use IDs from your data as keys.
When you don't have stable IDs for rendered items, you may use the item index as a key
as a last resort.
Bad Practice
// Missing key for component
[<Hello />, <Hello />, <Hello />];
// Missing key for each element data
data.map(x => <Hello>{x}</Hello>);
// Invalid Syntax: `key` attribute before spread
<span key={"key-after-spread"} {...spread} />;
// Missing `key` attribute
data.map(x => <>{x}</>);
Recommended
// Updated component with key
[<Hello key="first" />, <Hello key="second" />, <Hello key="third" />];
// Updated component with key for array `data`
data.map((x, i) => <Hello key={i}>{x}</Hello>);
// `key` attribute after spread
<span {...spread} key={"key-after-spread"} />;
// Updated `key` attribute
data.map(x => <key="key">{x}</>);