React-Router v4+로 페이지 제목을 변경할 수 있는 방법이 있습니까?
React-Router v4+가 위치를 변경할 때 페이지 제목을 변경하는 방법을 찾고 있습니다.Redx 로케이션 변경 액션을 듣고 그 루트를 체크하고metaData
물건.
React-Router v4+를 사용하는 경우 고정 경로 목록은 없습니다.실제로 사이트 주변의 다양한 컴포넌트는Route
같은 패스 스트링을 사용합니다.그 말은 내가 쓰던 방법이 더 이상 통하지 않는다는 거야.
주요 루트가 변경되었을 때 액션을 호출하여 페이지 제목을 갱신할 수 있는 방법이 있습니까?아니면 사이트의 메타데이터를 갱신할 수 있는 더 좋은 방법이 있습니까?
<Route />
컴포넌트에는 렌더 속성이 있습니다.따라서 다음과 같이 루트를 선언함으로써 로케이션이 변경되었을 때 페이지 제목을 변경할 수 있습니다.
<Route
exact
path="/"
render={props => (
<Page {...props} component={Index} title="Index Page" />
)}
/>
<Route
path="/about"
render={props => (
<Page {...props} component={About} title="About Page" />
)}
/>
인Page
component는 루트 제목을 설정할 수 있습니다.
import React from "react"
/*
* Component which serves the purpose of a "root route component".
*/
class Page extends React.Component {
/**
* Here, we define a react lifecycle method that gets executed each time
* our component is mounted to the DOM, which is exactly what we want in this case
*/
componentDidMount() {
document.title = this.props.title
}
/**
* Here, we use a component prop to render
* a component, as specified in route configuration
*/
render() {
const PageComponent = this.props.component
return (
<PageComponent />
)
}
}
export default Page
2019년 8월 1일 갱신.이것은 react-module > = 4.x에서만 작동합니다.@supremebing7 덕분에
다음 컴포넌트를 사용하여 임의의 경로의 제목을 지정할 수 있습니다.이 컴포넌트는 를 사용하여 구축됩니다.useEffect
.
import { useEffect } from "react";
const Page = (props) => {
useEffect(() => {
document.title = props.title || "";
}, [props.title]);
return props.children;
};
export default Page;
그리고 나서Page
에서render
루트 프롭:
<Route
path="/about"
render={(props) => (
<Page title="Index">
<Index {...props} />
</Page>
)}
/>
<Route
path="/profile"
render={(props) => (
<Page title="Profile">
<Profile {...props} />
</Page>
)}
/>
고객님의 고객명componentDidMount()
방법 모든 페이지에 대해 이 작업을 수행합니다.
componentDidMount() {
document.title = 'Your page title here';
}
그러면 페이지 제목이 변경되어 모든 경로에 대해 위에서 언급한 작업을 수행합니다.
또한 제목 부분보다 더 많은 경우 react-helmet을 확인하십시오. 이 기능은 매우 깔끔한 라이브러리이며, 몇 가지 멋진 엣지 케이스도 처리합니다.
phen0menon의 훌륭한 답변에서 따온다면, 대신 확장해보는 것은 어떨까요?
import React, { useEffect } from 'react';
import { Route } from 'react-router-dom';
import PropTypes from 'prop-types';
export const Page = ({ title, ...rest }) => {
useEffect(() => {
document.title = title;
}, [title]);
return <Route {...rest} />;
};
이렇게 하면 다음과 같이 오버헤드 코드가 제거됩니다.
// old:
<Route
exact
path="/"
render={props => (
<Page {...props} component={Index} title="Index Page" />
)}
/>
// improvement:
<Page
exact
path="/"
component={Index}
title="Index Page"
/>
업데이트: 커스텀 훅을 사용하는 방법도 있습니다.
import { useEffect } from 'react';
/** Hook for changing title */
export const useTitle = title => {
useEffect(() => {
const oldTitle = document.title;
title && (document.title = title);
// following line is optional, but will reset title when component unmounts
return () => document.title = oldTitle;
}, [title]);
};
메인 라우팅 페이지의 기능 컴포넌트를 사용하면 useEffect를 사용하여 각 경로의 제목을 변경할 수 있습니다.
예를들면,
const Routes = () => {
useEffect(() => {
let title = history.location.pathname
document.title = title;
});
return (
<Switch>
<Route path='/a' />
<Route path='/b' />
<Route path='/c' />
</Switch>
);
}
Tierry Prosts 솔루션을 기반으로 구축한 결과 다음과 같은 결과가 나왔습니다.
업데이트 2020년 1월: 구성 요소도 Typescript로 업데이트했습니다.
2021년 8월 업데이트: TypeScript에 개인 루트를 추가했습니다.
import React, { FunctionComponent, useEffect } from 'react';
import { Route, RouteProps } from 'react-router-dom';
interface IPageProps extends RouteProps {
title: string;
}
const Page: FunctionComponent<IPageProps> = props => {
useEffect(() => {
document.title = "Website name | " + props.title;
});
const { title, ...rest } = props;
return <Route {...rest} />;
};
export default Page;
업데이트: My Page.jsx 컴포넌트는 이제 기능 컴포넌트가 되었습니다.useEffect 훅이 있는 경우:
import React, { useEffect } from 'react';
import { Route } from 'react-router-dom';
const Page = (props) => {
useEffect(() => {
document.title = "Website name | " + props.title;
});
const { title, ...rest } = props;
return <Route {...rest} />;
}
export default Page;
아래에는 초기 솔루션이 나와 있습니다.
// Page.jsx
import React from 'react';
import { Route } from 'react-router-dom';
class Page extends Route {
componentDidMount() {
document.title = "Website name | " + this.props.title;
}
componentDidUpdate() {
document.title = "Website name | " + this.props.title;
}
render() {
const { title, ...rest } = this.props;
return <Route {...rest} />;
}
}
export default Page;
라우터의 실장은 다음과 같습니다.
// App.js / Index.js
<Router>
<App>
<Switch>
<Page path="/" component={Index} title="Index" />
<PrivateRoute path="/secure" component={SecurePage} title="Secure" />
</Switch>
</App>
</Router>
개인 경로 설정:
// PrivateRoute
function PrivateRoute({ component: Component, ...rest }) {
return (
<Page
{...rest}
render={props =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/",
state: { from: props.location }
}}
/>
)
}
/>
);
}
TypeScript의 개인 경로:
export const PrivateRoute = ({ Component, ...rest }: IRouteProps): JSX.Element => {
return (
<Page
{...rest}
render={(props) =>
userIsAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: Paths.login,
state: { from: props.location },
}}
/>
)
}
/>
);
};
이를 통해 퍼블릭 영역 모두 새로운 제목으로 업데이트하고 프라이빗 영역도 업데이트할 수 있게 되었습니다.
헬멧의 약간의 도움을 받아:
import React from 'react'
import Helmet from 'react-helmet'
import { Route, BrowserRouter, Switch } from 'react-router-dom'
function RouteWithTitle({ title, ...props }) {
return (
<>
<Helmet>
<title>{title}</title>
</Helmet>
<Route {...props} />
</>
)
}
export default function Routing() {
return (
<BrowserRouter>
<Switch>
<RouteWithTitle title="Hello world" exact={true} path="/" component={Home} />
</Switch>
</BrowserRouter>
)
}
설정이나 마찬가지의 .document.title
, 「」를 사용합니다.useEffect
/**
* Update the document title with provided string
* @param titleOrFn can be a String or a function.
* @param deps? if provided, the title will be updated when one of these values changes
*/
function useTitle(titleOrFn, ...deps) {
useEffect(
() => {
document.title = isFunction(titleOrFn) ? titleOrFn() : titleOrFn;
},
[...deps]
);
}
에만 다시 수 .deps
re never. 다시렌더링하지 않음다음과 같이 합니다.
const Home = () => {
useTitle('Home');
return (
<div>
<h1>Home</h1>
<p>This is the Home Page</p>
</div>
);
}
(렌더)의 userId
★★★★
const UserProfile = ({ match }) => {
const userId = match.params.userId;
useTitle(() => `Profile of ${userId}`, [userId]);
return (
<div>
<h1>User page</h1>
<p>
This is the user page of user <span>{userId}</span>
</p>
</div>
);
};
// ... in route definitions
<Route path="/user/:userId" component={UserProfile} />
// ...
여기에 CodePen이 있지만 프레임 제목을 업데이트할 수 없습니다.
「 」를 하면,<head>
변경 내용을 확인할 수 있습니다.
컴포넌트 내의 반복을 피하기 위해 한 단계 더 나아가서 제목을 한 곳(라우터 모듈)에서 갱신할 수 있다고 생각하기 때문에 이 답변을 드렸습니다.
평소에는 루트를 어레이로 선언하고 있습니다만, 스타일에 따라 실장을 변경할 수 있습니다.기본적으로 이런 ==>
import {useLocation} from "react-router-dom";
const allRoutes = [
{
path: "/talkers",
component: <Talkers />,
type: "welcome",
exact: true,
},
{
path: "/signup",
component: <SignupPage />,
type: "onboarding",
exact: true,
},
]
const appRouter = () => {
const theLocation = useLocation();
const currentLocation = theLocation.pathname.split("/")[1];
React.useEffect(() => {
document.title = `<Website Name> |
${currentLocation[0].toUpperCase()}${currentLocation.slice(1,)}`
}, [currentLocation])
return (
<Switch>
{allRoutes.map((route, index) =>
<Route key={route.key} path={route.path} exact={route.exact} />}
</Switch>
)
}
또 은 '다 하다'라는에 이미 '다'가 있다고 입니다.allRoutes
@Denis Skiba @Denis Skiba @Denis Skiba 。
'다, 하다, 하다'로 갈 수도 있어요.render
const routes = [
{
path: "/main",
component: MainPage,
title: "Main Page",
exact: true
},
{
path: "/about",
component: AboutPage,
title: "About Page"
},
{
path: "/titlessPage",
component: TitlessPage
}
];
const Routes = props => {
return routes.map((route, idx) => {
const { path, exact, component, title } = route;
return (
<Route
path={path}
exact={exact}
render={() => {
document.title = title ? title : "Unknown title";
console.log(document.title);
return route.component;
}}
/>
);
});
};
codesandbox 예제(제목 참조에 대한 새 창이 열립니다)
리액트 헬메트를 사용해 주세요.Typescript의 예를 들어보겠습니다.
import { Helmet } from 'react-helmet';
const Component1Title = 'All possible elements of the <head> can be changed using Helmet!';
const Component1Description = 'No only title, description etc. too!';
class Component1 extends React.Component<Component1Props, Component1State> {
render () {
return (
<>
<Helmet>
<title>{ Component1Title }</title>
<meta name="description" content={Component1Description} />
</Helmet>
...
</>
)
}
}
상세: https://github.com/nfl/react-helmet#readme
Dan Abramov(Redux의 크리에이터이자 현재 React 팀의 멤버)는 제목을 설정하기 위한 컴포넌트를 만들었습니다.이 컴포넌트는 React Router의 새로운 버전에서도 사용할 수 있습니다.매우 사용하기 쉽고 자세한 내용은 여기를 참조하십시오.
https://github.com/gaearon/react-document-title
예:
<DocumentTitle title='My Web App'>
언급URL : https://stackoverflow.com/questions/52447828/is-there-a-way-to-modify-the-page-title-with-react-router-v4
'source' 카테고리의 다른 글
JSX react/react-in-jsx-scope를 사용할 때 'React'가 범위에 있어야 합니까? (0) | 2023.02.22 |
---|---|
Basic Respect 폼 제출 시 페이지 전체가 갱신됩니다. (0) | 2023.02.22 |
엔티티 없이 스프링 저장소 생성 (0) | 2023.02.22 |
Woocommerce - woocommerce_locate_template 대체 수단 (0) | 2023.02.22 |
Contact Form 7에서 스판 래퍼를 제거하려면 어떻게 해야 합니까? (0) | 2023.02.22 |