Comments (17)
Just use hooks.
function useDocumentTitle(title) {
const originalTitle = document.title;
useEffect(
() => {
document.title = title;
return () => {
document.title = originalTitle;
};
},
[title, originalTitle]
);
}
from react-document-title.
Seeing as the last release is back in 12 Apr 2017, I just had to solve this for myself and ended up using react-helmet
for a drop-in replacement of DocumentTitle
.
// custom-document-title.tsx
import React from "react";
import Helmet from "react-helmet";
export type IDocumentTitleProps = {
title?: string;
children?: React.ReactElement;
};
export function DocumentTitle(props: IDocumentTitleProps) {
const { title, children } = props;
return (
<>
<Helmet>
<title>{title}</title>
</Helmet>
{children}
</>
);
}
export default DocumentTitle;
Usage, exactly the same as react-document-title
and nested declarations work just as you'd expect. Drop-in replacement for this package.
import DocumentTitle from "./custom-document-title"
<DocumentTitle title="My Title">
from react-document-title.
Yeah I think essentially the heavy lifting here is handled by react-side-effect, and react-side-effect depends on componentWillMount. The issue for that is here: gaearon/react-side-effect#54
Dan stated in that issue that react-side-effect doesn't really make sense to him anymore and that a more modern approach might be to use context. It looks like react-helmet-async is doing just that, so maybe that's the way to go.
from react-document-title.
What's needed to make this happen? Does a solution need to be picked by the maintainers (it seems like context is the way to go?) Is a PR needed?
The last comment here is from 2019; how can we make this happen in 2020?
from react-document-title.
If anyone is looking for a short hook solution that matches this package behavior, this should do it:
import React from 'react';
const DEFAULT_PAGE_TITLE = 'My Website';
const DocumentTitleContext = React.createContext(DEFAULT_PAGE_TITLE);
/**
* Update the page title with the given prop
* NOTE: We use a context so that we can restore the title to whichever value is specified by the nearest parent
*/
export const DocumentTitle = ({
title,
children,
}: {
title: string;
children: React.ReactNode;
}) => {
const parentTitle = React.useContext(DocumentTitleContext);
React.useEffect(() => {
document.title = title;
return () => {
document.title = parentTitle;
};
}, [title, parentTitle]);
return <DocumentTitleContext.Provider value={title}>{children}</DocumentTitleContext.Provider>;
};
Previous solutions that snapshot the title in useEffect
didn't seem to work for me and were causing flickering in the title. This approach should consistently restore the title to the one defined by the nearest parent.
from react-document-title.
@gaelduplessix maybe i am missing something, but with your solution, if you nest several DocumentTitle
<DocumentTitle title="top title">
<DocumentTitle title="title">
<DocumentTitle title="inner title">
<h1>some content</h1>
</DocumentTitle>
</DocumentTitle>
</DocumentTitle>
final document.title
will be top title
not the inner title
from react-document-title.
"react": "^16.9.0",
"react-document-title": "^2.0.3",
"react-dom": "^16.9.0",
"react-loadable": "^5.5.0",
"react-router-dom": "^5.0.1",
```
from react-document-title.
We had not merged the pull request, because of problems in react-document-title
there is not lite way to replace componentWillMount → componentDidMount here.
more info: gaearon/react-side-effect#40 (comment)
from react-document-title.
Interested by this too.
from react-document-title.
need upgrade this package?
from react-document-title.
@mmakarin this will not actually reset the title, because originalTitle
updates on the next render. Something like this should work though:
function useDocumentTitle(title) {
useEffect(
() => {
const originalTitle = document.title;
document.title = title;
return () => {
document.title = originalTitle;
};
},
[title]
);
}
from react-document-title.
So your solution works @Hypnosphi solution is on my branch (ignore the tests, they're broken for the reason following) https://github.com/erindepew/react-document-title/tree/convert-to-hooks the only problem is that it seems to also require a change for withSideEffect https://github.com/gaearon/react-side-effect in order to get the .rewind() and .peek(), and I'm not sure there's a way to do that without componentWillMount. Thoughts?
from react-document-title.
One issue with the hooks approach is that nested components don't take precedence over their parents: https://codesandbox.io/s/interesting-bartik-stwys (see useDocumentTitle.ts and useDocumentTitle.test.tsx)
Given that children are mounted before parents I'm not really sure what the best approach to solving this would be. Especially tricky when you consider sibling components as well and determining which should take precedence
Edit: I think I might just be re-stating what @erindepew said above
from react-document-title.
Great point, completely forgot about that as well. So seems like refactoring to hooks isn't really an option for this component.
from react-document-title.
Please, fix this issue
from react-document-title.
I think you should use https://github.com/staylor/react-helmet-async instead.
<HelmetProvider>
<App>
<Helmet>
<title>Hello World</title>
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
from react-document-title.
@ptboyer I believe your solution will still generate a warning, because react-helmet
uses react-side-effect
. I had come up with a very similar drop-in replacement using react-helmet-async
.
import React from 'react';
import { Helmet } from 'react-helmet-async';
interface Props {
children?: React.ReactNode;
title: string;
}
export const DocumentTitle = ({ children, title }: Props) =>
<>
<Helmet>
<title>{title}</title>
</Helmet>
{children}
</>;
Note: We don't use default exports in our project. You'll still need to setup the HelmetProvider
as described earlier in the comments
from react-document-title.
Related Issues (20)
- mistake
- Blocks context propagation HOT 3
- Memory leak on server side! HOT 7
- React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. HOT 4
- Patch release 2.0.3 with new dependencies
- Should use the deepest truthy value
- Suffix support? HOT 2
- Support export.default? HOT 1
- Use of React.Children.only() HOT 2
- Leads to memory leaks when it's used with renderToString HOT 2
- TypeError: Cannot read property 'string' of undefined at eval HOT 1
- Keep seeing warnings about missing 'key' prop for DocumentTitle HOT 2
- Upgrade to ESM
- Support FormattedMessage from react-intl HOT 3
- Readme file Reservations
- DocumentTitle is undefined when running tests HOT 5
- Issues with importing when using TypeScript HOT 3
- When I use it.Why components has been an empty object at this.props?
- Fix DT Typing to indicate only one child HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-document-title.