我正在使用各种组件状态的上下文,在这种情况下,选中了该复选框,并正在使用该组件来改变该组件状态。但是,通过仅单击一个复选框,将重新渲染所有四个组件(复选框)。钩入上下文并更改上下文时,如何防止这种重新渲染?谢谢。
index.tsx:
import * as React from "react";
import ReactDOM from "react-dom";
import { ContextProvider, useMyContext } from "./context";
import "./styles.css";
const Checkbox: React.FC<{ id: number }> = ({ id }) => {
React.useEffect(() => console.log(`Checkbox ${id} Render`));
const { setValue, value } = useMyContext();
return (
<input
onClick={() => setValue(id)}
checked={id === value}
type="checkbox"
/>
);
};
const Container: React.FC = () => {
React.useEffect(() => console.log("Container Render"));
return (
<div>
{[0, 1, 2, 3].map(id => (
<Checkbox id={id} />
))}
</div>
);
};
const App: React.FC = () => {
return (
<ContextProvider>
<Container />
</ContextProvider>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
context.tsx:
import * as React from "react";
interface ContextState {
setValue: (id: number) => void;
value: number;
}
const initialContextState: ContextState = {
setValue: () => {},
value: 0
};
const Context = React.createContext<ContextState>(initialContextState);
export const ContextProvider: React.FC = (props: object) => {
const [value, setValue] = React.useState<number>(0);
return (
<Context.Provider
value={{
setValue,
value
}}
{...props}
/>
);
};
export const useMyContext = (): ContextState => React.useContext(Context);
答案 0 :(得分:1)
您不能阻止重新渲染上下文消耗组件(在您的示例中为Checkbox
)-更新上下文值时强制重新渲染只是Context API的工作方式,您不能应用任何对其具有“选择性”。
您可以 采取的措施是将消耗组件的实际内容中的昂贵部分提取出来,将其提取为用React.memo
包裹的子组件(或内联为JSX块)包裹在useMemo
钩子-docs中),从上下文中获取所需的值,并将这些作为道具传递给该子组件/依赖项到useMemo
部分。
然后,内置备忘录将“正常工作”,并且不会为实际值未更新的复选框重新渲染子组件(昂贵的部分),因为相关的道具不会改变。
使用这样的备注可以解决您需要解决的任何实际性能问题,但仅提醒您,在90%的时间里,这些东西都没有关系。在以这种方式重构组件之前,测试并确定性能实际上是一个问题。通常,根本不值得使用额外的间接方法来解决非问题!
答案 1 :(得分:0)