如何解决如何使用自定义钩子和 useContext 仅呈现相关组件
我正在尝试基于 useContext 创建一个自定义钩子 useFocus 以仅将焦点设置在我选择的组件上。 它可以工作,但即使我使用 useCallback 作为我的 useFocus 自定义钩子返回的函数,其他组件也在呈现。
我只想重新渲染焦点不断变化的组件。
我知道如果代码很快,重新渲染可能是小问题,但我不明白为什么要重新渲染。 你能给我一些解释或修复吗。
预期结果:
当点击“设置焦点”按钮时,我希望得到:
1 个 A/B/D 渲染
2 个 C/E 渲染
谢谢。
这是我的代码:
import React,{ createContext,useCallback,useContext,useState } from "react";
import "./styles.css";
const StepContext = createContext({});
//This is just to display number or render for each Items
function useRenderCounter() {
const ref = React.useRef();
React.useEffect(() => {
ref.current.textContent = Number(ref.current.textContent || "0") + 1;
});
return (
<span
style={{
backgroundColor: "#ccc",borderRadius: 4,padding: "2px 4px",fontSize: "0.8rem",margin: "0 6px",display: "inline-block"
}}
ref={ref}
/>
);
}
const useFocus = (property) => {
const context = useContext(StepContext);
const bool = context === property;
//console.log("bool",bool,context,property);
//return bool
return useCallback(() => bool,[bool]);
};
const Item = React.memo(({ property }) => {
const rendercounter = useRenderCounter();
const isFocus = useFocus(property);
//Here I expect to got re-render only for property which the focus changed
const focus = isFocus();
console.log(property,"render",focus);
const style = focus ? { borderStyle: "solid",borderColor: "red" } : {};
return (
<div style={{ display: "flex",margin: "4px" }}>
{rendercounter}
<div style={style}>{property}</div>
</div>
);
});
export default function App() {
const [focusOn,setFocusOn] = useState("E");
const handleClick = () => setFocusOn("C");
return (
<StepContext.Provider value={focusOn}>
<div style={{ display: "flex",flexDirection: "column" }}>
<Item key={1} property={"A"} />
<Item key={2} property={"B"} />
<Item key={3} property={"C"} />
<Item key={4} property={"D"} />
<Item key={5} property={"E"} />
<button onClick={handleClick}>set focus</button>
</div>
</StepContext.Provider>
);
}
解决方法
当 Provider 获得新值时,无法避免重新渲染。来自official docs on Context API:
当 Provider 的 value prop 发生变化时,所有作为 Provider 后代的消费者都会重新渲染。从 Provider 到其后代消费者(包括 .contextType 和 useContext)的传播不受 shouldComponentUpdate 方法的约束,因此即使祖先组件跳过更新,消费者也会更新。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。