Created
May 15, 2025 19:42
-
-
Save bilalbhojani24/036ca6b37d325b8594431168824e79e5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createRoot } from "react-dom/client"; | |
import React, { | |
createContext, | |
useContext, | |
useEffect, | |
useState, | |
useRef, | |
} from "react"; | |
const DocumentTitleContext = createContext({ | |
registerTitle: () => {}, | |
unregisterTitle: () => {}, | |
}); | |
/** | |
* DocumentTitleProvider tracks the deepest mounted title and sets document.title accordingly | |
*/ | |
export function DocumentTitleProvider({ children }) { | |
const [titles, setTitles] = useState([]); | |
const registerTitle = (title, id) => { | |
setTitles((prev) => [...prev, { id, title }]); | |
}; | |
console.log(titles); | |
const unregisterTitle = (id) => { | |
setTitles((prev) => prev.filter((t) => t.id !== id)); | |
}; | |
useEffect(() => { | |
if (titles.length > 0) { | |
const latestTitle = titles[0].title; | |
document.title = latestTitle; | |
} | |
}, [titles]); | |
return ( | |
<DocumentTitleContext.Provider value={{ registerTitle, unregisterTitle }}> | |
{children} | |
</DocumentTitleContext.Provider> | |
); | |
} | |
/** | |
* DocumentTitle sets the document title while mounted, respecting nesting | |
*/ | |
export function DocumentTitleWrapper({ documentTitle, element }) { | |
const { registerTitle, unregisterTitle } = useContext(DocumentTitleContext); | |
const idRef = useRef(Symbol()); // Unique and stable per instance | |
useEffect(() => { | |
registerTitle(documentTitle, idRef.current); | |
return () => { | |
unregisterTitle(idRef.current); | |
}; | |
}, [documentTitle]); | |
return <>{element}</>; | |
} | |
const Child2 = () => { | |
return <h1>Child2</h1>; | |
}; | |
const Child3 = () => { | |
return <h1>Child3</h1>; | |
}; | |
const Child = () => { | |
return ( | |
<h1> | |
Child | |
<DocumentTitleWrapper documentTitle="Child2" element={<Child2 />} /> | |
<DocumentTitleWrapper documentTitle="Child3" element={<Child3 />} /> | |
</h1> | |
); | |
}; | |
const Parent = () => { | |
return ( | |
<h1> | |
parent | |
<DocumentTitleWrapper documentTitle="Child" element={<Child />} /> | |
</h1> | |
); | |
}; | |
export default function App() { | |
useEffect(() => { | |
console.log("App"); | |
}, []); | |
return ( | |
<DocumentTitleProvider> | |
<div className="App"> | |
<DocumentTitleWrapper documentTitle="App" element={<Parent />} /> | |
</div> | |
</DocumentTitleProvider> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment