Як встановити заголовок документа в React?


107

Я хотів би встановити заголовок документа (у рядку заголовка браузера) для моєї програми React. Я спробував використати response-document-title (здається застарілим) і встановити document.titleв constructorі componentDidMount()- жодне з цих рішень не працює.


застарілий? @DanAbramov Я думаю, реакція-документ-заголовок добре працює і з React16.
JS, розробник

Підтверджую, реакція-заголовок документа чудово працює з реакцією 16.5
Джо-Го

Відповіді:


81

Ви можете використовувати 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>
        ...
      </>
    )
  }
}

це "спалахне" вміст index.html в першу секунду, так?
nxmohamad

3
Це, безумовно, має бути головною відповіддю. Це чудовий декларативний спосіб управління заголовком та іншими метаатрибутами
Райал

113
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')
);

Це працює для мене.

Редагувати: якщо ви використовуєте webpack-dev-server, встановіть для рядка значення true


4
Це працює, але заголовок документа все ще "React App", поки сторінка завантажується - будь-яка ідея, як це виправити?
eli

7
Змініть вміст тегу заголовка у вашому index.html
AlexVestin,

4
Краще це зробити декларативно, як у відповіді @ quotesBro
Ryall

1
Це нормально для SEO?
Davidm176,

@AlexVestin Не гарна ідея, якщо вам потрібні різні назви для різних поглядів у вашому додатку React
Кевін

51

Для React 16.8 ви можете зробити це за допомогою функціонального компонента за допомогою useEffect .

Наприклад:

useEffect(() => {
   document.title = "new title"
}, []);

Маючи другий аргумент як виклик масиву, useEffect використовується лише один раз, роблячи його схожим на componentDidMount.


Як це можна перевірити за допомогою жарту та ферментів?
nickstaroba

16

Як вже згадували інші, ви можете використовувати document.title = 'My new title'і React Helmet для оновлення заголовка сторінки. Обидва ці рішення все одно відображатимуть початковий заголовок "React App" перед завантаженням скриптів.

Якщо ви використовуєте початкове назва документа встановлюється в тег файлу.create-react-app<title>/public/index.html

Ви можете редагувати це безпосередньо або використовувати заповнювач, який буде заповнений із змінних середовища:

/.env:

REACT_APP_SITE_TITLE='My Title!'
SOME_OTHER_VARS=...

Якщо з якихось причин я хотів інший заголовок у своєму середовищі розробки -

/.env.development:

REACT_APP_SITE_TITLE='**DEVELOPMENT** My TITLE! **DEVELOPMENT**'
SOME_OTHER_VARS=...

/public/index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
         ...
         <title>%REACT_APP_SITE_TITLE%</title>
         ...
     </head>
     <body>
         ...
     </body>
</html>

Цей підхід також означає, що я можу прочитати змінну середовища заголовка сайту з мого додатка, використовуючи глобальний process.envоб'єкт, що приємно:

console.log(process.env.REACT_APP_SITE_TITLE_URL);
// My Title!

Див .: Додавання користувацьких змінних середовища


Переконайтеся, що файли .env розміщені на одному рівні з файлом package.json. :)
Ян Сміт,

10

ви повинні встановити заголовок документа в життєвому циклі 'componentWillMount':

componentWillMount() {
    document.title = 'your title name'
  },

7
componentWillMount () застаріло в останній
реакційній

3
У цьому випадку, як і в більшості випадків, коли вам доводиться видаляти застарілий компонентWillMount, перемістіть свій код до компонентаDidMount
Jo-Go

9

Портали React можуть дозволити вам відображати елементи поза кореневим вузлом React (наприклад, at <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;

Просто помістіть компонент на сторінку та встановіть pageTitle:

<Title pageTitle="Dashboard" />
<Title pageTitle={item.name} />

Ого, виглядає так багатообіцяюче, React Helmet та document.title обидва працюють, але це приголомшливо :) Дякую
mamsoudi

Мені сподобалось це рішення, поки я не зрозумів, що воно просто додається fullTitleдо вмісту, вже знайденого в index.html <title>Default Title</title>.
JWess

Просто видаліть заголовок за замовчуванням у вашому модулі (не в constructor!) `` Імпортувати React з ' імпортувати PropTypes із 'prop-типів'; імпортувати ReactDOM з 'response-dom'; const titleNode = document.getElementsByTagName ("заголовок") [0]; titleNode.innerText = ''; експортувати за замовчуванням Заголовок класу розширює React.PureComponent {static propTypes = {children: PropTypes.node,}; конструктор (props) {супер (props); this.el = titleNode; } render () {return ReactDOM.createPortal (this.props.children, this.el,); }} `` `
Анатолій Літинський

9

У React 16.13 ви можете встановити його безпосередньо всередині функції візуалізації:

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')
)

Для функціонального компонента:

function App() {
    document.title = 'wow'
    return <p>Hello</p>
}

1
Це типова помилка, яка зустрічається в багатьох базах коду реагування: НЕ РОБІТЬ ТО! Кожні методи візуалізації повинні бути чистими функціями (без побічних ефектів), якщо вам потрібно виконати побічний ефект: useEffect для функціональних компонентів або подій компонентів у класах (докладніше: reddit.com/r/reactjs/comments/8avfej/… )
Еліас Платек

6

Просто ви можете створити функцію у файлі js та експортувати її для використання у компонентах

як нижче:

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

і використовувати його в будь-якому такому компоненті:

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

3

Ви можете використовувати наступне нижче з 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')
);

або Ви можете використовувати цей пакет 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')
);

Щасливого кодування !!!


2

Я не перевіряв це надто ретельно, але, здається, це працює. Написано TypeScript.

interface Props {
    children: string|number|Array<string|number>,
}

export default class DocumentTitle extends React.Component<Props> {

    private oldTitle: string = document.title;

    componentWillUnmount(): void {
        document.title = this.oldTitle;
    }

    render() {
        document.title = Array.isArray(this.props.children) ? this.props.children.join('') : this.props.children;
        return null;
    }
}

Використання:

export default class App extends React.Component<Props, State> {

    render() {
        return <>
            <DocumentTitle>{this.state.files.length} Gallery</DocumentTitle>
            <Container>
                Lorem ipsum
            </Container>
        </>
    }
}

Не впевнений, чому інші прагнуть розмістити весь свій додаток всередині свого <Title>компонента, це здається мені дивним.

Оновивши document.titleвнутрішню частину, render()вона оновиться / буде в курсі, якщо вам потрібен динамічний заголовок. Він також повинен повернути заголовок, якщо його не демонтувати. Портали милі, але здаються непотрібними; нам насправді не потрібно маніпулювати будь-якими DOM-вузлами тут.


2

Ви можете використовувати ReactDOM і <title>тег зміни

ReactDOM.render(
   "New Title",
   document.getElementsByTagName("title")[0]
);

0

Я використовую цей метод, який я з’ясував, оскільки мені це простіше. Я використовую його в поєднанні з функціональним компонентом. Робіть це лише в тому випадку, якщо вам байдуже, що на ньому не відображатиметься жоден заголовок, якщо користувач вимкне Javascript на вашій сторінці.

Вам потрібно зробити дві речі.

1. Зайдіть у свій index.html і видаліть цей рядок тут

<title>React App</title>

2. Зайдіть у свою функцію mainapp і поверніть це, що є звичайною структурою html, ви можете скопіювати та вставити основний вміст із веб-сайту між тегами тіла:

return (
        <html>
          <head>
            <title>hi</title>
          </head>
          <body></body>
        </html>
      );

Ви можете замінити заголовок як завгодно.


-7

Якщо ви новачок, ви можете просто врятувати себе від усього цього, перейшовши у загальну папку папки вашого проекту з реагуванням та відредагувавши заголовок у "index.html" і поставивши свій. Не забудьте зберегти, щоб це відображалося.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.