我有一个简单的应用程序与报头.tsx
组件,应该是可用于所有页面和家.tsx
,其中大部分内容将是.
家.tsx
承载一个intersectionObserver
,它将带有use语境
钩子(称为homeLinks
)的数据发送到报头.tsx
槽APP.tsx
,因此我可以使用当前相交部分的类更新导航.这里的问题是:只要观察者更新上下文,整个DOM就会重新呈现,因为家将首当其冲地占据应用程序的首位,这不可能是最佳解决方案.谁能给我解释一下如何以正确的方式做到这一点?
我可以用某种方式将裁判从首页发送到标题,然后在那里设置观察者吗?
CodeSandbox demo is available here个
APP
import homeLinks from "./contexts/homeLinks";
function APP() {
const [homePart, set家Part] = useState<string>(""); //家 part which is observed, setting function
console.log("APP is rendered");
return (
<>
<homeLinks.Provider value={{ homePart, set家Part }}>
<报头 /> {/* Outside router, meant to be shared with other pages */}
<家 /> {/* Will be in react router */}
</homeLinks.Provider>
</>
);
}
export default APP;
家
import homeLinks from "../contexts/homeLinks";
export const 家 = () => {
const homeParts = useRef(new Array());
const { set家Part } = use语境(homeLinks);
useEffect(() => {
const menuObserver = new IntersectionObserver(
(entries) => {
const entry = entries[0];
if (entry.isIntersecting)
set家Part(
entry.target.getAttribute("id")
? entry.target.getAttribute("id")!
: "ntn here",
);
},
{ rootMargin: "-40% 0px -50% 0px" },
);
homeParts.current.map((part) => {
menuObserver.observe(part!);
});
}, []);
console.log("家 is rendered");
return (
<>
<div
className="hero"
id="home"
ref={(element) => homeParts.current.push(element)}
>
<section>
<div className="depth"></div>
<div className="heroContent">
<h1>This is 家</h1>
</div>
</section>
</div>
<div
id="projects"
style={{ height: "100vh", backgroundColor: "gray" }}
ref={(element) => homeParts.current.push(element)}
>
This is Projects
</div>
<div
id="contact"
style={{ height: "100vh", backgroundColor: "cadetblue" }}
ref={(element) => homeParts.current.push(element)}
>
This is contact
</div>
</>
);
};
报头
import linkSection from "../contexts/homeLinks";
function 报头() {
const lastHash = useRef("");
const { homePart } = use语境(linkSection);
const homeLinks = [
{ href: "home", title: "家" },
{ href: "projects", title: "Projects" },
{ href: "contact", title: "Contact" },
];
return (
<header>
<div>
<a href="/">Menu</a>
</div>
<nav>
<ul>
{homeLinks.map((homeLink) => (
<li key={homeLink.href}>
<a
href={"/#" + homeLink.href}
className={homePart == homeLink.href ? "active" : ""}
>
{homeLink.title}
</a>
</li>
))}
</ul>
</nav>
</header>
);
}
export default 报头;
语境
import { create语境 } from "react";
const homeLinks = create语境({
homePart: "",
set家Part: (part: string) => {},
});
export default homeLinks;
完整的代码也可以在https://codesandbox.io/p/devbox/9p6fyv?file=%2Fsrc%2Fcontexts%2FhomeLinks.tsx&embed=1中找到