【问题标题】:React, update individual value from button click反应,通过按钮单击更新单个值
【发布时间】:2025-12-19 21:05:07
【问题描述】:

我正在尝试创建一个列表,您可以在其中单击左侧的按钮,它会为您提供右侧项目的摘要。状态数组更新和新项目被添加到列表中,但项目数量的文本不会更新。仅当我强制另一个渲染或直到我将不同的项目添加到列表中时,数量才会增加。

[截图][1]: https://i.stack.imgur.com/XW7PU.png

有没有办法更新数量的文本视图?

export default function EquipmentSelect() {
    const [selectedEquipment, setSelectedEquipment] = useState([]);

    const equipmentList = [
        { name: 'item 1', id: '0111' },
        { name: 'item 3', id: '0112' },
        { name: 'item 5', id: '0113' },
        { name: 'item 6', id: '0114' },
        { name: 'item 7', id: '0115' },
        { name: 'item 8', id: '0116' },
        { name: 'item 9', id: '0116' },
        { name: 'item 10', id: '0117' },
        { name: 'item 11', id: '0118' },
        { name: 'item 12', id: '0119' },
    ]

    const handleButtonClick = (event, value) => {
        if (!handleCheck(value)) {
            setSelectedEquipment(selectedEquipment => [...selectedEquipment, { key: value.id, name: value.name, quantity: 1 }])
        }
        else {
            const selectedItemIndex = selectedEquipment.findIndex(item => item.key === value.id)
            selectedEquipment[selectedItemIndex] = {
                ...selectedEquipment[selectedItemIndex], quantity: selectedEquipment[selectedItemIndex].quantity + 1
            }
        }
    }
    function handleCheck(value) {
        return selectedEquipment.some(item => value.name === item.name);
    }

    return (
        <div class='equipmentContainer divRowFlex'>
            <div class='addEquipment'>
                <Autocomplete
                    freeSolo
                    options={equipmentList.map((option) => option.name)}
                    renderInput={(params) => <TextField {...params} label="Type to search..." />}
                />
                <List sx={{
                    width: '100%',
                    position: 'relative',
                    overflow: 'auto',
                    maxHeight: 300,
                    '& ul': { padding: 0 },
                }}>
                    {equipmentList.map((value) => (
                        <ListItem
                            key={value}
                            disableGutters
                            secondaryAction={
                                <IconButton
                                    onClick={(event) => handleButtonClick(event, value)}
                                >
                                    <MdAddCircle size='18' className='text-secondary my-auto' />
                                </IconButton>
                            }
                        >
                            <ListItemText primary={`${value.name}`} />
                        </ListItem>
                    ))}
                </List>
            </div>
            <div class='selectedEquipment divColFlex'>
                <div class='divRowFlex selectedEquipmentHeader'>
                    <h1>Selected Equipment:</h1>
                    <h1>QTY</h1>
                </div>
                <div class='selectedEquipmentItemContainer '>
                    {selectedEquipment.map(item =>
                        <div class='divRowFlex selectedEquipmentItem'>
                            <h2>{item.name}</h2>
                            <h2>{item.quantity}</h2>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:
    selectedEquipment[selectedItemIndex] = {
                    ...selectedEquipment[selectedItemIndex], quantity: selectedEquipment[selectedItemIndex].quantity + 1
                }
    

    没有调用setState,因此不会强制重新渲染

    setSelectedEquipment(prev=> {
      prev[selectedItemIndex] = {
                    ...prev[selectedItemIndex], quantity: prev[selectedItemIndex].quantity + 1
                }
     return prev
    }
    

    将使用重新渲染执行相同的逻辑

    【讨论】:

    • 我试过了,它似乎没有改变任何东西。我用你的改动替换了最初的 selectedEquipment。
    • 你应该用第二个块替换我答案中附加的第一个代码块
    【解决方案2】:

    我设法找到了解决方案。这是因为我从未更新状态数组。

                let newArry = [...selectedEquipment]
                const selectedItemIndex = newArry.findIndex(item => item.key === value.id)
                newArry[selectedItemIndex] = {
                    ...newArry[selectedItemIndex], quantity: newArry[selectedItemIndex].quantity + 1
                }
                setSelectedEquipment(newArry)
            }
    

    【讨论】: