Bagaimana Anda mengatur judul dokumen di React?

114

Saya ingin menyetel judul dokumen (di bilah judul browser) untuk aplikasi React saya. Saya telah mencoba menggunakan react-document-title (tampaknya kedaluwarsa) dan pengaturan document.titledi constructordan componentDidMount()- tidak ada solusi ini yang berfungsi.

eli
sumber
kadaluarsa? @DanAbramov Saya rasa react-document-title bekerja dengan baik dengan React16 juga.
JS dev
Saya mengonfirmasi, react-document-title bekerja sangat baik dengan react 16,5
DevTheJo

Jawaban:

91

Anda dapat menggunakan 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>
        ...
      </>
    )
  }
}
quotesBro
sumber
1
ini akan 'mem-flash' konten index.html di detik pertama, bukan?
nxmohamad
3
Ini pasti jawaban teratas. Ini adalah cara deklaratif yang sangat baik untuk mengelola judul dan atribut meta lainnya
Ryall
120
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')
);

Ini berhasil untuk saya.

Edit: Jika Anda menggunakan webpack-dev-server set inline to true

AlexVestin
sumber
5
Ini berfungsi tetapi judul dokumen masih "Aplikasi React" saat halaman sedang dimuat - ada ide bagaimana cara memperbaikinya?
eli
7
Ubah konten tag judul di index.html Anda
AlexVestin
4
Lebih baik melakukannya secara deklaratif seperti dalam jawaban @ quotesBro
Ryall
1
Apakah cara ini OK untuk SEO?
Davidm176
@AlexVestin Bukan ide yang baik jika Anda membutuhkan judul yang berbeda untuk tampilan yang berbeda dalam aplikasi React Anda
Kevin
55

Untuk React 16.8, Anda dapat melakukan ini dengan komponen fungsional menggunakan useEffect .

Sebagai contoh:

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

Memiliki argumen kedua sebagai array memanggil useEffect hanya sekali, membuatnya mirip dengan componentDidMount.

Jordan Daniels
sumber
Bagaimana ini bisa diuji dengan lelucon dan enzim?
nickstaroba
20

Seperti yang disebutkan orang lain, Anda dapat menggunakan document.title = 'My new title'dan React Helmet untuk memperbarui judul halaman. Kedua solusi ini masih akan membuat judul 'React App' awal sebelum skrip dimuat.

Jika Anda menggunakan create-react-appyang awal judul dokumen diatur dalam <title>tag /public/index.htmlberkas.

Anda dapat mengedit ini secara langsung atau menggunakan placeholder yang akan diisi dari variabel lingkungan:

/.env:

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

Jika karena alasan tertentu saya menginginkan judul yang berbeda di lingkungan pengembangan saya -

/.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>

Pendekatan ini juga berarti bahwa saya dapat membaca variabel lingkungan judul situs dari aplikasi saya menggunakan process.envobjek global , yang bagus:

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

Lihat: Menambahkan Variabel Lingkungan Kustom

Gruffy
sumber
Pastikan untuk meletakkan file .env pada level yang sama dengan file package.json Anda. :)
Ian Smith
10

Anda harus menetapkan judul dokumen dalam siklus hidup 'componentWillMount':

componentWillMount() {
    document.title = 'your title name'
  },
Alvin
sumber
10
componentWillMount () tidak digunakan lagi dalam versi react terbaru 16
Hemadri Dasari
3
Dalam kasus ini, seperti di sebagian besar kasus waktu, ketika Anda harus menghapus componentWillMount yang tidak digunakan lagi, pindahkan kode Anda ke componentDidMount
DevTheJo
10

Portal React memungkinkan Anda merender ke elemen di luar node root React (seperti di <title>), seolah-olah itu adalah node React yang sebenarnya. Jadi sekarang Anda dapat menyetel judul dengan bersih dan tanpa ketergantungan tambahan:

Berikut contohnya:

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;

Cukup letakkan komponen di halaman dan setel pageTitle:

<Title pageTitle="Dashboard" />
<Title pageTitle={item.name} />
Kolonel Tiga Puluh Dua
sumber
Wow, terlihat sangat menjanjikan, React Helmet dan document.title keduanya berfungsi, tapi ini luar biasa :) Terima kasih
mamsoudi
Saya menyukai solusi ini sampai saya menyadari bahwa itu hanya menambahkan fullTitleke konten yang sudah ditemukan di index.html <title>Default Title</title>.
JWess
Hapus saja judul default di modul Anda (bukan di constructor!) `` Import React from 'react'; impor PropTypes dari 'prop-types'; impor ReactDOM dari 'react-dom'; const titleNode = document.getElementsByTagName ("title") [0]; titleNode.innerText = ''; ekspor kelas default Judul extends React.PureComponent {static propTypes = {children: PropTypes.node,}; konstruktor (alat peraga) {super (alat peraga); this.el = titleNode; } render () {return ReactDOM.createPortal (this.props.children, this.el,); }} ``
Anatoliy Litinskiy
9

Di React 16.13, Anda dapat mengaturnya langsung di dalam fungsi render:

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

Untuk komponen fungsi:

function App() {
    document.title = 'wow'
    return <p>Hello</p>
}
M Imam Pratama
sumber
2
Ini adalah kesalahan umum yang muncul di banyak basis kode react: JANGAN LAKUKAN! Setiap metode render harus merupakan fungsi murni (tanpa efek samping), jika Anda perlu melakukan efek samping: useEffect untuk komponen fungsional, atau peristiwa komponen di kelas (info selengkapnya: reddit.com/r/reactjs/comments/8avfej/… )
Elias Platek
6

Cukup Anda dapat membuat fungsi dalam file js dan mengekspornya untuk digunakan dalam komponen

seperti dibawah ini:

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

dan gunakan di komponen apa pun seperti ini:

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
amin msh
sumber
3

Anda dapat menggunakan yang berikut di bawah ini dengan 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')
);

atau Anda dapat menggunakan paket npm ini 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')
);

Selamat Coding !!!

EsterlingAccime Youtuber
sumber
2

Saya belum menguji ini terlalu teliti, tetapi ini sepertinya berhasil. Ditulis dalam 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;
    }
}

Pemakaian:

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

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

Tidak yakin mengapa orang lain tertarik untuk menempatkan seluruh aplikasi mereka di dalam <Title>komponen mereka , itu tampak aneh bagi saya.

Dengan memperbarui bagian document.titledalamnya, render()itu akan menyegarkan / tetap up to date jika Anda menginginkan judul yang dinamis. Ini harus mengembalikan judul saat dilepas juga. Portal itu lucu, tapi sepertinya tidak perlu; kita tidak perlu memanipulasi simpul DOM apa pun di sini.

mpen
sumber
2

Anda dapat menggunakan ReactDOM dan mengubah <title>tag

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

Sejak React 16.8. Anda dapat membuat pengait khusus untuk melakukannya (mirip dengan solusi @Shortchange):

export function useTitle(title) {
  useEffect(() => {
    const prevTitle = document.title
    document.title = title
    return () => {
      document.title = prevTitle
    }
  })
}

ini dapat digunakan dalam komponen reaksi apa pun, misalnya:

const MyComponent = () => {
  useTitle("New Title")
  return (
    <div>
     ...
    </div>
  )
}

Ini akan memperbarui judul segera setelah komponen dipasang dan mengembalikannya ke judul sebelumnya ketika dilepas.

Tuan Bruce
sumber
0

Saya menggunakan metode ini, yang saya temukan karena lebih mudah bagi saya. Saya menggunakannya dalam kombinasi dengan komponen fungsi. Lakukan ini hanya, jika Anda tidak peduli bahwa itu tidak akan menampilkan judul apa pun jika pengguna menonaktifkan Javascript di halaman Anda.

Ada dua hal yang perlu Anda lakukan.

1. Masuk ke index.html Anda dan hapus baris ini di sini

<title>React App</title>

2. Masuk ke fungsi mainapp Anda dan kembalikan ini yang hanya merupakan struktur html biasa, Anda dapat menyalin dan menempelkan konten utama Anda dari situs web Anda di antara tag tubuh:

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

Anda dapat mengganti judul sesuai keinginan.

Makusium
sumber
0
const setTitle = (title) => {
  const prevTitle = document.title;
  document.title = title;
  return () => document.title = prevTitle;
}

const MyComponent = () => {
  useEffect(() => setTitle('Title while MyComponent is mounted'), []);

  return <div>My Component</div>;
}

Ini adalah solusi yang cukup langsung yang saya buat saat bekerja hari ini. setTitlemengembalikan fungsi yang menyetel ulang judul ke apa yang sebelumnya digunakan setTitle, itu bekerja dengan sangat baik di dalam useEffecthook React .

Shortchange
sumber
1
Ini adalah cara yang benar untuk melakukannya. Tapi, pasti akan menyenangkan tidak harus melakukannya. Konsepnya cukup dapat digunakan kembali hanya dengan npm.
Eugene Kuzmenko
-8

Jika Anda seorang pemula, Anda dapat menyelamatkan diri dari semua itu dengan masuk ke folder publik dari folder proyek react Anda dan edit judul di "index.html" dan masukkan milik Anda. Jangan lupa simpan agar tercermin.

Stanleynd
sumber