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

React Native中状态数组无法添加对象的问题排查

React状态更新无效问题排查与修复

我尝试更新一个包含对象数组的状态,但状态完全没有变化!我遵循了React官方文档,也查看了许多带有相同解决方案的类似问题,但对我来说就是不起作用。以下是我的代码:

const [chips, setChips] = useState<Chip[]>([]);
const [chipColor, setChipColor] = useState(null);
const [chipValue, setChipValue] = useState("");

function addChip(color: string) {
    if (chips.length >= 10) {
        alert("É permitido no máximo 10 fichas.")
        return;
    }

    const chip: Chip = {color: color, value: chipValue}
    setChips([...chips, chip])
    // setChips(prev => [...prev, chip]) doesn't work either
    console.log("WHYYYY")
    setData({...formData, chips})
    setChipValue(null)
    setChipColor(null)
}

function handleClose(e, id) {
    setChips(chips.filter(chip => chip.value !== id))
}

return (<VStack space="2.5" minW={"250"} justifyContent='center' alignContent='center'>
        <FormControl>
            <FormControl.Label _text={{bold: true}}>Valor</FormControl.Label>
            <Input
                size={"lg"}
                keyboardType='numeric'
                value={chipValue}
                onChangeText={text => {
                    setChipValue(text?.replace(/[^0-9]/g, ''))
                }}
                maxLength={4}
            />
        </FormControl>
        <FormControl>
            <FormControl.Label _text={{bold: true}}>Cor</FormControl.Label>
            <Select selectedValue={chipColor} minWidth="200" accessibilityLabel="Escolha a cor"
                    placeholder="Escolha a cor"
                    size={"lg"}
                    _selectedItem={{
                        bg: chipColor,
                        endIcon: <CheckIcon size="5"/>
                    }}
                    onValueChange={colorValue => {
                        addChip(colorValue)
                    }}>
                {colors.map((color, i) => {
                    return <Select.Item key={i} label={color.name} value={color.value}/>
                })}
            </Select>
        </FormControl>
        <Stack
            flexWrap={"wrap"}
            direction="row"
            justifyContent={"center"}
            space={3}>
            {chips.map((chip, i) => {
                return (<CloseableCircle size="40px"
                                         bg={chip.color}
                                         shadow="9"
                                         handleClose={(e) => handleClose(e, chip.value)}
                                         key={i}>
                    <Text color={"white"} bold borderColor={"black"}>{chip.value}</Text>
                </CloseableCircle>)
            })}
        </Stack>
        <StepsButtonGroup setPage={setPage} pages={pages} currentPage={currentPage}/>
    </VStack>
);

问题根源

  1. 异步状态更新导致旧值引用
    setChips是异步操作,调用后chips不会立刻更新为新值。你在setChips之后直接用旧的chips去更新formData,导致formData无法拿到最新的芯片列表。

  2. 闭包捕获旧状态
    handleClose中直接使用chips.filter,当组件重新渲染时可能捕获到旧的chips状态,导致过滤逻辑无法正确更新数组。

修复方案

1. 先创建新数组,统一使用新值更新状态

在addChip里先构建好新的芯片数组,再用这个数组同步更新chips和formData:

function addChip(color: string) {
    if (chips.length >= 10) {
        alert("É permitido no máximo 10 fichas.")
        return;
    }
    // 新增:校验芯片值是否为空
    if (!chipValue) {
        alert("请输入芯片值");
        return;
    }

    const newChip: Chip = {color, value: chipValue};
    const newChips = [...chips, newChip];
    setChips(newChips);
    // 如果formData更新依赖旧值,建议用函数式更新
    setData(prev => ({...prev, chips: newChips}));
    setChipValue(null);
    setChipColor(null);
}

2. 依赖当前状态的更新改用函数式写法

对于handleClose,使用函数式更新确保拿到最新的状态:

function handleClose(e, id) {
    setChips(prevChips => prevChips.filter(chip => chip.value !== id));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:35:42