所以我有一个负责渲染项目列表的父级。单击该项目时,它将向父级发送一个事件,该事件将在 map 上记录选择状态。如果选择,它会将选定状态传递给子级,以便它可以更改样式。这是父级的代码:
export default function CreateYourMixProductsList(props: ProductsInterface) {
const selectedProducts: Map<number, Product> = new Map<number, Product>();
function onProductClick(product: Product): void {
selectedProducts.set(product.id, product);
}
return (
<>
<List sx={{width: '100%', bgcolor: 'background.paper'}}>
{props?.products?.map(product => (
<ProductListItem key={product.id} product={product}
selected={selectedProducts.has(product.id)}
onClick={(product) => onProductClick(product)} />
))}
</List>
</>
);
和 child
export default function ProductListItem(props: ProductProps) {
const [selected, setSelected] = React.useState(false);
function onClick(product: Product) {
props.onClick(product);
}
useEffect(() => {
setSelected(!selected);
}, [props.selected]);
return (
<>
<ListItemButton alignItems="flex-start" onClick={event => {onClick(props.product)}} selected={props.selected ? selected : false}>
//omitted code to keep it short
useEffect 仅在渲染时触发,而据我了解,每次传递的 props 是不可变变量时都应该触发它。我在这里缺少什么?
最佳答案
让我们打开这个:
为什么 useEffect 没有运行?
每次依赖项数组中的变量发生更改时, Hook 都会重新运行。您的钩子(Hook)不会再次运行,因为 props.selected
的值没有更改。
您只需在组件中记录该值即可轻松验证这一点。
为什么 props.selected
没有改变?
您的点击处理程序正确设置了 map
上的值。但是,React 无法识别映射内设置的新值。该组件永远不会重新渲染,也不会再次调用 selectedProducts.has()
。所以 props.selected
的值确实还是一样。
如何让 React 识别您的更改?
首先,您应该避免在组件中声明这样的状态。每次渲染此组件时,它都会重新声明其中定义的所有变量(selectedProducts
将始终设置为新的空映射)。使用 react hook api相反。
要使变量保持不变并具有反应性,您只需将其与 useState()
一起使用,就像在子组件中所做的那样。例如:
...
const [selectedProducts, setSelectedProducts] = useState<Map<number, Product>>(new Map<number, Product>());
function onProductClick(product: Product): void {
selectedProducts.set(product.id, product);
// Note how we are re-setting the variable to make React aware of the change!
setSelectedProducts(new Map(selectedProducts));
}
...
需要注意的是,Reacts useState
钩子(Hook)会将值与三等号 (===
) 进行比较,以确定是否应该触发重新渲染。由于 JavaScript 的性质(其中变量仅保存对对象的引用),在 Map 上设置新值不会更改其引用。要触发重新渲染,您必须替换 map 。
创建新对象的计算成本很低,因此大多数时候这不会导致任何问题。
关于reactjs - react : Hook not triggering when parent component changes boolean value passed to child,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70230207/