javascript - 让孩子们的道具相互独立——因为它们来自同一个 .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 导入的)
解决方案
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}>
// ...
)
}
推荐阅读
- git - 这是避免自动合并的有效 git 工作流程吗?
- javascript - 关于房间创建和删除的 Socket.io 事件
- neo4j - apoc.periodic.commit 不会导致更新
- xpages - 从 xp:dialog 创建文档 - 对象已被删除或回收
- extjs - 无法在 Ext.grid.PagingToolbar Extjs 上绑定存储
- android - 在 Ubuntu 18.04 上缺少适用于 Android 的 Xamarin 文件
- vue.js - vue js app yarn serve 失败,退出代码为 1。?
- node.js - 我应该为每条路线创建新的模式模型文件还是使用已经创建的模式?
- php - Laravel 中 Session::flash() 和 with() 的区别
- javascript - 选定范围识别