0

I'm trying to update a state where there is an object array, but it somehow doesn't change state at all! I'm following this docs https://react.dev/learn/updating-arrays-in-state and checked many similar questions with the very same solution, but it simply doesn't work for me. Here's the code:

    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>
    );
}```
3
  • 2
    I don't know what setData does, but you're calling it with the old chips value. This might be the cause. Additionally, make sure you're always changing the values with the prev value: in the function itself, the value of chip is "frozen" to the value when addChip was created, i.e. [], so accessing doesn't achieve what you hope for (google for inlining for more explanations on that matter). Same for the setData calls - use prev.
    – NotX
    Commented Jun 19, 2023 at 16:16
  • 1
    Does this answer your question? Why does calling react setState method not mutate the state immediately?
    – Abe
    Commented Jun 19, 2023 at 20:37
  • @NotX Even using the arrow function with prevState didn´t work, either Commented Jun 28, 2023 at 21:27

1 Answer 1

0

Solved by removing setData from addChip and moving it to a kind of "Submit" button, with setData(prevState -> ({...prevState, chips: chips}). Somehow setData (setData: ({chips, ...otherProps}) => void) was changing chips values, then it was always setting the old value.

Thanks, guys! Using useEffect to handle async state change didn´t help, as Abe suggested question answers suggests.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.