首页 > 解决方案 > 让孩子们的道具相互独立——因为它们来自同一个 .map

问题描述

我在数组中添加具有以下 onClick 事件的元素addElement (状态为:) const [add,setAdd]=React.useState([]):(父组件中的处理程序)

const handleClickAddgroup = (event) => {
        setAdd([...add,
            {id: getUid(), ...ourObject}
        ])
    }

这是每个项目的选择方式:

const handleProduct = (value,key) => {
        setProduct(key,value);
    };

addElement在父组件中,我想为数组 中的每个元素呈现ControlledOpenSelect组件:

{addElement.map(item=>{
            return <ControlledOpenSelect ourObject={ourObject} key={item.id} onRemove={handleRemoveAGroup} item={item} onChange={handleProduct} 
            handleClose={handleClose} handleOpen={handleOpen} handleQuantity={handleQuantity} handleRemoveAGroup={handleRemoveAGroup} price={price}
            subTotal={subTotal} product={product} open={open}/>
        })} 

ControlledOpenSelect本身看起来像这样:

const ControlledOpenSelect=({ourObject,item,handleOpen,handleClose,onChange,handleQuantity,handleRemoveAGroup,price,product,subTotal,open})=>{

    const handleProduct=(event)=>{
        onChange(item.id,event.target.value)
    }

    return (
        <div>
            <Button onClick={handleOpen}>
                        Open the select
      </Button>
                    <FormControl >
                        <InputLabel id="demo-controlled-open-select-label">Product</InputLabel>
                        <Select **I think in this component is a problem**
                            labelId="demo-controlled-open-select-label"
                            id="demo-controlled-open-select"
                            open={open}
                            onClose={()=>handleClose()}
                            onOpen={()=>handleOpen()}
                            value={product}
                            onChange={handleProduct}
                            key={item.id}
                        >
                            {Object.entries(item).filter(([key]) => key !== 'id').map(
                                ([key, value]) => <MenuItem key={key} value={key}>{key}</MenuItem>
                            )}
                        </Select>
                        <div>
                            <TextField id="outlined-basic" label="Quantity" variant="outlined" onChange={(event)=>handleQuantity(event)} key={item.id}/>
                            <TextField id="outlined-basic" label="Price" variant="outlined" value={price} disabled key={item.id}/>
                            <p>{Number.isFinite(subTotal) ? subTotal : 0}</p>
                        </div>
                    </FormControl>
                    <button type="button" onClick={()=>handleRemoveAGroup(item.id)}>Delete</button>
        </div>
    )
}

我的问题是,每次我在一个渲染的孩子中更改某些内容时,它都会将道具更改为显示的每个孩子。我不得不提一下,我确实知道,仅在这种特殊情况下,最好将状态移动到ControlledOpenSelect其中,但这对我来说并不是一个真正的选择,因为我想将状态保留在父级中,因为我将需要它们。非常感谢!(PS 任何其他未提及的组件都是从 Material UI 导入的)

标签: javascriptreactjsreact-native

解决方案


memo使用更高的顺序包装您的孩子(人)组件:

export default React.memo(function myChild(props) {

})

useCallBack在将主要状态更改功能作为道具传递给孩子时,您需要使用钩子。例如

function ParentCMPNT() {
   const [x,setX] = React.useState();

   const handleXupdate = React.useCallBack((value)=>setX(value),[]); // add dependencies too.
   return (
       <MyChild onUpdate={handleXupdate}>
       <MyChild onUpdate={handleXupdate}>
       // ...

   )
}


推荐阅读