每次遍历 products 数组时,我都会渲染 Items 组件。有一个按钮(“show Gallery”)可以触发产品组件的渲染并显示产品。当我渲染 Items 组件时,我也总是渲染复选框。有没有办法可以隔离复选框组件以保留选中状态?因为现在每当单击“显示画廊”按钮时,我都会重新渲染所有内容,并且再次取消选中我的复选框。我希望我的问题足够清楚。谢谢
const otherComponent = () => {
//set showGallery globally to true or false
}
const Gallery = () => {
const products =[...]
return (
{showGallery &&
<Child products={products}/>
}
)
}
const Child = ({products}) => {
return (
<div>
{products.map((product)=> {
return <Item name={product.name}/>
})}
</div>
)
}
const Item = ({name}) => {
const handleFilter = () => {
//call function that filters products and other logic
}
return (
//...code
<h1>{name}</h1>
<Checkbox handleFilter={handleFilter}/>
//...code
)
}
const Checkbox = ({handleFilter}) => {
const [checked, setChecked] = React.useState(false)
const checkStyle = checked ? "show" : "hide"
const handleCheckbox = () => {
setChecked(!checked)
handleFilter(checked)
}
return (
<button
className="checkbox"
onClick={() => handleCheckbox()}
>
<Checkmark className={`${checkStyle} checkmark`} />
</button>
)
}
答案 0 :(得分:1)
您可以创建一个 CheckboxProvider
来存储每个复选框的选中状态
import React from "react";
export const CheckboxContext = React.createContext({});
const CheckboxProvider = ({ children }) => {
const [checkboxState, setCheckboxState] = React.useState({});
const saveCheckboxState = (key, val) => {
setCheckboxState({
...checkboxState,
[key]: val
});
};
React.useEffect(() => {
console.log(checkboxState);
}, [checkboxState]);
return (
<CheckboxContext.Provider
value={{
state: checkboxState,
saveCheckboxState
}}
>
{children}
</CheckboxContext.Provider>
);
};
export default CheckboxProvider;
然后用 return
包裹 Gallery
的 CheckboxProvider
的内容
Gallery.js
const Gallery = () => {
// ...
return (
<CheckboxProvider>
<button onClick={() => setShowGallery(!showGallery)}>
{showGallery ? "Hide Gallery" : "Show Gallery"}
</button>
{showGallery && <Child products={products} />}
</CheckboxProvider>
)
}
并像这样消耗复选框的状态:
Checkbox.js
const Checkbox = (id, handleFilter) => {
const { state, saveCheckboxState } = React.useContext(CheckboxContext);
// ...
}
有关演示,请参阅 CODESANDBOX。