【问题标题】:react router (react-router-dom) setting page title from current route (functional components)?从当前路由(功能组件)反应路由器(react-router-dom)设置页面标题?
【发布时间】:2021-01-13 15:38:25
【问题描述】:

我认为这很容易,但仍然找不到简单的解决方案。我只是想将页面标题(和 document.title)设置为我选择的指定字符串。我知道我可以访问 useLocation 并获取当前路线,但这不适用于合乎逻辑的人工命名。例如,我的路线可能是 /new,但我希望页面的标题是“添加新事物”。 请注意,我为页面标题添加了一个新道具,这似乎是添加它的合理位置(然后使用 useEffect 拉取它),但不知道如何访问此道具。

如果这不是正确的方法,你会怎么做?我是否应该为当前 url(useLocation) 设置一个字典/查找并分配一个人工页面标题?

主要目标:如果有人直接点击 URL '/new',您将如何设置标题?

我当前的结构来自一个基本的创建反应应用程序。

在我的 index.js 中

ReactDOM.render(
    <React.StrictMode>
      <Router>
        <App />
      </Router>
    </React.StrictMode>,
    document.getElementById('root')
);

app.js

<div className="quiz-app-row">
        <SideBarNav />
        <div className='quiz-app-col'>
          <h1>{TITLE HEREEEEE}</h1>
          <Switch>
            <Route exact component={Home} path="/" title='home' />
            <Route exact component={Example} path="/manage" title='example' />
            <Route exact component={CreateQuiz} path="/new" title='New Quiz' />
          </Switch>
        </div>
      </div>

【问题讨论】:

  • 你不想用动态标题替换&lt;h1&gt;TITLE HEREEEEE&lt;/h1&gt;吗?
  • @TaghiKhavari 是的,但是由于我还没有办法访问 的标题属性,所以我什至没有显示它。我会编辑它以防其他人感到困惑。

标签: reactjs react-router react-router-dom page-title


【解决方案1】:

我认为根据您的应用组件来完成您想要完成的工作的最佳方法是为您的标题使用上下文,如下所示:

首先像这样创建标题上下文:

const TitleContext = React.createContext();
const useTitle = () => React.useContext(TitleContext);

const TitleProvider = ({ children }) => {
  const [title, setTitle] = useState("THIS IS DEFAULT TITLE");

  return (
    <TitleContext.Provider value={{ title, setTitle }}>
      {children}
    </TitleContext.Provider>
  );
};

那么你需要稍微改变一下你的应用组件

const App = () => {
  const { title } = useTitle();

  return (
    <div className="quiz-app-row">
      <SideBarNav />
      <div className="quiz-app-col">
        <h1>{title}</h1>
        <Switch>
          <Route exact component={Home} path="/" title="home" />
          <Route exact component={Example} path="/manage" title="example" />
          <Route exact component={CreateQuiz} path="/new" title="New Quiz" />
        </Switch>
      </div>
    </div>
  );
};

也像这样在 TitleProvider 中包装你的 App 组件:

ReactDOM.render(
  <React.StrictMode>
    <TitleProvider>
      <Router>
        <App />
      </Router>
    </TitleProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

最后你可以像这样在组件中设置标题

const Home = () => {
  const { setTitle } = useTitle();

  React.useEffect(() => {
    setTitle('This is human readable title for Home Component')
  }, [])

  return <div>I'm Home Component</div>;
};

【讨论】:

    【解决方案2】:

    使用react-helmet动态设置标题

    使用安装

    npm install --save react-helmet
    

    现在,当您安装 react-helmet 后,只需将此片段放在任何地方即可使用它

    import {Helmet} from "react-helmet";
    ...
    <Helmet>
        <title>My title</title>
    </Helmet>
    

    示例方法

    您可以在不同的文件中创建自己的route 变体

    import React from "react";
    import {Helmet} from "react-helmet";
    
    const RouteWithTitle = ({ component: Component, title, ...rest}) => (
       <Route {...rest} render={(props)=> (
           <Helmet>
               <title>{title}</title>
           </Helmet>
           <Component {...routeProps} />
       )} />
    )
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      感谢大家的回复,但我觉得他们中的大多数似乎对于我想要完成的事情来说太过分了,并且不需要额外的包。相反,我只是创建了一个查找集合并以这种方式分配了标题。我总共只有大约 7 个链接,所以这似乎是可以管理的。

      const [pageTitle, setPageTitle] = useState('Home');
      
        const titleMap = [
          {path: '/', title:'Home'},
          {path: '/manage', title:'Manage'},
          {path: '/new', title:'New Quiz'}
        ]
      
        let curLoc = useLocation();
        useEffect(() => {
          const curTitle = titleMap.find(item => item.path === curLoc.pathname)
          if(curTitle && curTitle.title){
            setPageTitle(curTitle.title)
            document.title = curTitle.title
          }
        }, [curLoc])
      

      【讨论】:

      • 只是评论评论,您的解决方案工作正常,但它使用命令式方法(即手动更新文档),而使用 react-helmet 是声明性方法
      【解决方案4】:

      在您的 CreateQuiz 组件上使用 document.title = "Add New Thing";。我不确定这是否是最好的方法。但它对我有用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-28
        • 2018-08-31
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 2018-04-04
        • 2021-02-07
        • 1970-01-01
        相关资源
        最近更新 更多