如何在React中设置文档标题?

eli*_*eli 52 javascript dom reactjs

我想为我的React应用程序设置文档标题(在浏览器标题栏中).我尝试过使用react-document-title(似乎已经过时了)并且设置document.title在- constructor并且componentDidMount()- 这些解决方案都不起作用.

Ale*_*tin 77

import React from 'react'
import ReactDOM from 'react-dom'


class Doc extends React.Component{
  componentDidMount(){
    document.title = "dfsdfsdfsd"
  }

  render(){
    return(
      <b> test </b>
    )
  }
}

ReactDOM.render(
  <Doc />,
  document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)

这适合我.

编辑:如果您使用webpack-dev-server设置内联为true

  • 更改index.html中标题标记的内容 (4认同)
  • 最好像@quotesBro的回答中那样声明性地执行 (4认同)
  • 此方法有效,但是页面加载时文档标题仍为“ React App”-知道如何解决吗? (2认同)
  • 这种方式适合SEO吗? (2认同)

quo*_*Bro 36

你也可以使用React Helmet:

import React from 'react'
import { Helmet } from 'react-helmet'

const TITLE = 'My Page Title'

class MyComponent extends React.PureComponent {
  render () {
    return (
      <>
        <Helmet>
          <title>{ TITLE }</title>
        </Helmet>
        ...
      </>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 设置一个 &lt;title&gt; 标签似乎有点过分了。 (45认同)
  • 这绝对应该是最佳答案。这是管理标题和其他元属性的绝佳声明方式 (6认同)
  • 就像@Reactgular 所说的那样,这太过分了。通常,不建议引入依赖项来解决可以使用现有可用工具轻松解决的问题。当然,API 可能比“document.title”更好,但您只是引入了潜在的更多复杂性,而通过添加对此类库的依赖并没有明显的好处。 (6认同)
  • 有没有办法像这样修改静态代码的模板?我们真的到了需要编写静态内容脚本的地步了吗? (4认同)
  • 这将在第一秒“闪烁”index.html 的内容,对吗? (2认同)
  • @Reactgular 同意。我更新了答案,指出头盔可用于管理所有头部标签,而不仅仅是标题。并添加了在 React 16.8+ 中使用 Effect hook 的示例 (2认同)

Mas*_*uce 14

从 React 16.8 开始。您可以构建一个自定义钩子来执行此操作(类似于@Shortchange 的解决方案):

export function useTitle(title) {
  useEffect(() => {
    const prevTitle = document.title
    document.title = title
    return () => {
      document.title = prevTitle
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

这可以用于任何反应组件,例如:

const MyComponent = () => {
  useTitle("New Title")
  return (
    <div>
     ...
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

它会在组件安装后立即更新标题,并在卸载时将其恢复为之前的标题。

  • 这个解决方案不应该将依赖项设置为 [] 以便它只在安装和卸载时运行吗? (9认同)
  • 如果我错了,请纠正我,但这仅适用于函数组件,不适用于类组件。 (3认同)
  • 现代 React 的最佳答案!重置标题的想法很棒。 (2认同)

Ale*_*tov 14

Helmet 确实是一个很好的方法,但是对于只需要更改标题的应用程序,这就是我使用的:(现代方式 React 解决方案 - 使用 Hooks)

  1. 创建更改页面标题组件
import React, { useEffect } from "react";

const ChangePageTitle = ({ pageTitle }) => {
  useEffect(() => {
    const prevTitle = document.title;
    document.title = pageTitle;
    return () => {
      document.title = prevTitle;
    };
  });

  return <></>;
};

export default ChangePageTitle;
Run Code Online (Sandbox Code Playgroud)
  1. 使用组件
import ChangePageTitle from "../{yourLocation}/ChangePageTitle";

...

return (
    <>
      <ChangePageTitle pageTitle="theTitleYouWant" />
      ...
    </>
  );

...
Run Code Online (Sandbox Code Playgroud)


M I*_*ama 12

如果你想知道,你可以直接在渲染函数中设置它:

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
    render() {
        document.title = 'wow'
        return <p>Hello</p>
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
)
Run Code Online (Sandbox Code Playgroud)

对于功能组件:

function App() {
    document.title = 'wow'
    return <p>Hello</p>
}
Run Code Online (Sandbox Code Playgroud)

但是,正如 Elias 在评论中所说,这是一种不好的做法

好的做法:

类组件:

class App extends React.Component {
    // you can also use componentDidUpdate() if the title is not static
    componentDidMount(){
        document.title = "good"
    }

    render() {
        return <p>Hello</p>
    }
}
Run Code Online (Sandbox Code Playgroud)

功能组件:

function App() {
    // for static title, pass an empty array as the second argument
    // for dynamic title, put the dynamic values inside the array
    // see: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
    useEffect(() => {
        document.title = 'good'
    }, []);

    return <p>Hello</p>
}
Run Code Online (Sandbox Code Playgroud)

  • 这是许多 React 代码库中出现的典型错误:不要这样做!每个渲染方法都应该是纯函数(无副作用),如果您需要执行副作用:功能组件的useEffect,或类中的组件事件(更多信息:https://www.reddit.com/r/reactjs/评论/8avfej/what_does_side_effects_mean_in_react/dx1xo1l) (6认同)

Shu*_*rda 11

对于 React v18+,自定义钩子将是最简单的方法。

第1步:创建一个钩子。(钩子/useDocumentTitle.js)

import { useEffect } from "react";
export const useDocumentTitle = (title) => {

    useEffect(() => {
        document.title = `${title} - WebsiteName`;
    }, [title]);

    return null;
}
Run Code Online (Sandbox Code Playgroud)

步骤2:根据该页面使用自定义标题在每个页面上调用钩子。(页面/HomePage.js)

import { useDocumentTitle } from "../hooks/useDocumentTitle";

const HomePage = () => {
    useDocumentTitle("Website Title For Home Page");
    
    return (
        <>           
            <main>
                <section>Example Text</section>
            </main>            
        </>
    );
}

export { HomePage };
Run Code Online (Sandbox Code Playgroud)

也适用于动态页面,只需传递产品标题或您想要显示的任何内容即可。


mar*_*ann 10

You have multiple options for this problem I would highly recommend to either use React Helmet or create a hook using useEffect. Instead of writing your own hook, you could also use the one from react-use:

React Helmet

import React from 'react';
import { Helmet } from 'react-helmet';

const MyComponent => () => (
  <Helmet>
    <title>My Title</title>
  </Helmet>
)
Run Code Online (Sandbox Code Playgroud)

react-use

import React from 'react';
import { useTitle } from 'react-use';

const MyComponent = () => {
  useTitle('My Title');

  return null;
}
Run Code Online (Sandbox Code Playgroud)


Alv*_*vin 9

你应该在'componentWillMount'的生命周期中设置文档标题:

componentWillMount() {
    document.title = 'your title name'
  },
Run Code Online (Sandbox Code Playgroud)

  • componentWillMount()在最新版本16中已弃用 (5认同)
  • 在这种情况下,与大多数情况下一样,当您必须删除不赞成使用的componentWillMount时,请将代码移至componentDidMount (2认同)

Jor*_*els 9

对于React 16.8,您可以使用useEffect对功能组件进行此操作

例如:

useEffect(() => {
   document.title = "new title"
}, []);
Run Code Online (Sandbox Code Playgroud)

将第二个参数作为数组使用时,只会调用一次useEffect,使其类似于componentDidMount


Sho*_*nge 8

import React from 'react';

function useTitle(title: string): void => {
  React.useEffect(() => {
    const prevTitle = document.title;
    document.title = title;

    return () => {
      document.title = prevTitle;
    };
  }, []);
}

function MyComponent(): JSX.Element => {
  useTitle('Title while MyComponent is mounted');

  return <div>My Component</div>;
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常直接的解决方案,useTitle设置文档标题,当组件卸载时,它会重置为之前的任何内容。

  • 这是正确的做法。但是,如果不必这样做肯定会很好。这个概念具有足够的可重用性,只需放在 npm 上即可。 (2认同)

Col*_*Two 7

React Portal可以让您渲染到根React节点之外的元素(例如<title>),就好像它们是实际的React节点一样。因此,现在您可以干净地设置标题,而无需任何其他依赖项:

这是一个例子:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Title extends Component {
    constructor(props) {
        super(props);
        this.titleEl = document.getElementsByTagName("title")[0];
    }

    render() {
        let fullTitle;
        if(this.props.pageTitle) {
            fullTitle = this.props.pageTitle + " - " + this.props.siteTitle;
        } else {
            fullTitle = this.props.siteTitle;
        }

        return ReactDOM.createPortal(
            fullTitle || "",
            this.titleEl
        );
    }
}
Title.defaultProps = {
    pageTitle: null,
    siteTitle: "Your Site Name Here",
};

export default Title;
Run Code Online (Sandbox Code Playgroud)

只需将组件放在页面中并设置pageTitle

<Title pageTitle="Dashboard" />
<Title pageTitle={item.name} />
Run Code Online (Sandbox Code Playgroud)


ami*_*msh 7

简单地,您可以在 js 文件中创建一个函数并将其导出以在组件中使用

像下面这样:

export default function setTitle(title) {
  if (typeof title !== "string") {
     throw new Error("Title should be an string");
  }
  document.title = title;
}
Run Code Online (Sandbox Code Playgroud)

并在任何组件中使用它,如下所示:

import React, { Component } from 'react';
import setTitle from './setTitle.js' // no need to js extension at the end

class App extends Component {
  componentDidMount() {
    setTitle("i am a new title");
  }

  render() {
    return (
      <div>
        see the title
      </div>
    );
  }
}

export default App
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用以下内容document.title = 'Home Page'

import React from 'react'
import { Component } from 'react-dom'


class App extends Component{
  componentDidMount(){
    document.title = "Home Page"
  }

  render(){
    return(
      <p> Title is now equal to Home Page </p>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

或者你可以使用这个 npm 包npm i react-document-title

import React from 'react'
import { Component } from 'react-dom'
import DocumentTitle from 'react-document-title';


class App extends Component{


  render(){
    return(
      <DocumentTitle title='Home'>
        <h1>Home, sweet home.</h1>
      </DocumentTitle>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

快乐编码!!!


Gru*_*ffy 5

正如其他人所说,你可以使用document.title = 'My new title'作出反应头盔更新页面标题。在加载脚本之前,这两种解决方案仍将呈现初始的“ React App”标题。

如果使用的create-react-app初始文档标题,则在<title>标记/public/index.html文件中设置。

您可以直接对其进行编辑,也可以使用将由环境变量填充的占位符:

/.env

REACT_APP_SITE_TITLE='My Title!'
SOME_OTHER_VARS=...
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因我想要在开发环境中使用其他标题-

/.env.development

REACT_APP_SITE_TITLE='**DEVELOPMENT** My TITLE! **DEVELOPMENT**'
SOME_OTHER_VARS=...
Run Code Online (Sandbox Code Playgroud)

/public/index.html

<!DOCTYPE html>
<html lang="en">
    <head>
         ...
         <title>%REACT_APP_SITE_TITLE%</title>
         ...
     </head>
     <body>
         ...
     </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这种方法还意味着我可以使用全局process.env对象从应用程序中读取网站标题环境变量,这很不错:

console.log(process.env.REACT_APP_SITE_TITLE_URL);
// My Title!
Run Code Online (Sandbox Code Playgroud)

请参阅:添加自定义环境变量

  • 我相信这是最合理的解决方案,除非您想更改组件内的标题 (2认同)