React'te belge başlığını nasıl belirlersiniz?


117

React uygulamam için belge başlığını (tarayıcının başlık çubuğunda) belirlemek istiyorum. Ben kullanarak denedi tepki-belge-başlık (güncel görünüyor) ve ayar document.titleiçinde constructorve componentDidMount()bu çözümler işin hiçbiri -.


tarihi geçmiş? @DanAbramov Sanırım react-document-title, React16 ile de iyi çalışıyor.
JS dev

Yanıtlar:


95

React Helmet'i kullanabilirsiniz :

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

1
bu ilk saniyede index.html'nin içeriğini 'flaş' edecek, değil mi?
nxmohamad

3
Bu kesinlikle en iyi cevap olmalı. Bu, başlığı ve diğer meta nitelikleri yönetmenin mükemmel bir açıklayıcı yolu
Ryall

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

Bu benim için çalışıyor.

Düzenleme: webpack-dev-server kullanıyorsanız satır içi olarak true olarak ayarlayın


5
Bu işe yarıyor, ancak sayfa yüklenirken belge başlığı hala "React Uygulaması" olarak kalıyor - bunu nasıl düzeltebileceğiniz hakkında bir fikriniz var mı?
eli


4
Bunu @ alıntılarda olduğu gibi bildirimsel olarak yapmak daha iyidirBro'nun cevabı
Ryall

1
Bu yol SEO için uygun mu?
Davidm176

@AlexVestin React uygulamanızda farklı görünümler için farklı başlıklara ihtiyacınız varsa iyi bir fikir değil
Kevin

60

React 16.8 için bunu useEffect kullanarak işlevsel bir bileşenle yapabilirsiniz .

Örneğin:

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

İkinci bağımsız değişkeni bir dizi olarak kullanmak useEffect'i yalnızca bir kez çağırır, bu da onu componentDidMount.


Bu nasıl jest ve enzimle test edilebilir?
nickstaroba

20

Diğerleri de söylediğim gibi, kullanabileceğiniz document.title = 'My new title've Helmet'e tepki sayfa başlığını güncellemek için. Bu çözümlerin her ikisi de komut dosyaları yüklenmeden önce ilk 'React Uygulaması' başlığını oluşturmaya devam edecektir.

Eğer kullanıyorsanız , ilk doküman başlığı ayarlanır etiketi dosyası.create-react-app<title>/public/index.html

Bunu doğrudan düzenleyebilir veya çevresel değişkenlerden doldurulacak bir yer tutucu kullanabilirsiniz:

/.env:

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

Herhangi bir nedenle geliştirme ortamımda farklı bir başlık isteseydim -

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

Bu yaklaşım aynı zamanda global process.envnesneyi kullanarak uygulamamdan site başlığı çevresel değişkenini okuyabileceğim anlamına da geliyor , bu güzel:

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

Bkz: Özel Ortam Değişkenleri Ekleme


.Env dosyalarını package.json dosyanızın aynı düzeyine koyduğunuzdan emin olun. :)
Ian Smith

10

Belge başlığını 'componentWillMount' yaşam döngüsünde ayarlamalısınız:

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

10
componentWillMount (), en son react sürüm 16
Hemadri Dasari,

3
Bu durumda, çoğu zaman olduğu gibi, kullanımdan kaldırılmış componentWillMount'u kaldırmanız gerektiğinde, kodunuzu
DevTheJo'ya

10

React Portalları , <title>gerçek React düğümleriymiş gibi, kök React düğümünün dışındaki öğelere (örneğin, at ) render etmenize izin verebilir . Artık başlığı temiz bir şekilde ve herhangi bir ek bağımlılık olmadan ayarlayabilirsiniz:

İşte bir örnek:

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;

Sadece bileşeni sayfaya yerleştirin ve ayarlayın pageTitle:

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

Vay be, çok umut verici görünüyor, React Helmet ve document.title ikisi de işe yarıyor, ama bu harika :) Teşekkürler
mamsoudi

Bu çözümü, yalnızca fullTitleindex.html dosyasında bulunan içeriğe eklendiğini anlayana kadar sevdim <title>Default Title</title>.
JWess

Modülünüzdeki varsayılan başlığı kaldırın (içinde değil constructor!) `` React'i 'react'ten içe aktarın; PropType'ları 'prop türlerinden' içe aktarın; ReactDOM'u 'react-dom'dan içe aktarın; const titleNode = document.getElementsByTagName ("title") [0]; titleNode.innerText = ''; varsayılan sınıfı dışa aktar Başlık, React.PureComponent'i genişletir {statik propTypes = {children: PropTypes.node,}; yapıcı (props) {süper (props); this.el = titleNode; } render () {return ReactDOM.createPortal (this.props.children, this.el,); }} ``
Anatoliy Litinskiy

9

React 16.13'te, bunu doğrudan render fonksiyonunun içinde ayarlayabilirsiniz:

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

Fonksiyon bileşeni için:

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

2
Bu, birçok tepki kodu tabanında görülen tipik bir hatadır: BUNU YAPMAYIN! Bir yan etki gerçekleştirmeniz gerekiyorsa, her işleme yöntemi saf işlevler olmalıdır (yan etki yok): işlevsel bileşenler için useEffect veya sınıflardaki bileşen olayları (daha fazla bilgi: reddit.com/r/reactjs/comments/8avfej/… )
Elias Platek

6

Basitçe bir js dosyasında bir işlev oluşturabilir ve bileşenlerdeki kullanımlar için dışa aktarabilirsiniz.

aşağıdaki gibi:

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

ve bunun gibi herhangi bir bileşende kullanın:

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

Aşağıdakileri ile kullanabilirsiniz 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')
);

veya bu npm paketini kullanabilirsiniz 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')
);

Mutlu Kodlama !!!


3

React 16.8'den beri. Bunu yapmak için özel bir kanca oluşturabilirsiniz (@Shortchange çözümüne benzer):

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

bu herhangi bir reaksiyon bileşeninde kullanılabilir, örneğin:

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

Bileşen takılır takılmaz başlığı günceller ve bağlantısı kesildiğinde önceki başlığa geri döndürür.


2

Bunu çok kapsamlı bir şekilde test etmedim, ancak bu işe yarıyor gibi görünüyor. TypeScript ile yazılmıştır.

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;
    }
}

Kullanım:

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

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

Değil emin diğerleri onların tüm app koyarak düşkün neden içeride kendi <Title>bileşeni, bana garip görünüyor.

Dinamik bir başlık istiyorsanız , document.titleiçini güncelleyerek render()yenilenir / güncel kalır. Aynısı da kaldırıldığında başlığı geri almalıdır. Portallar sevimli, ancak gereksiz görünüyor; Burada herhangi bir DOM düğümünü gerçekten değiştirmemize gerek yok.


2

ReactDOM'u ve değiştirme <title>etiketini kullanabilirsiniz

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

1
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>;
}

Bu, bugün çalışırken birlikte attığım oldukça basit bir çözüm. setTitlebaşlığı kullanmadan önceki haline sıfırlayan bir işlev döndürür setTitle, React'in useEffectkancasının içinde harika bir şekilde çalışır .


1
Bunu yapmanın doğru yolu budur. Ama buna mecbur olmamak güzel olurdu. Konsept, sadece npm'de olacak kadar yeniden kullanılabilir.
Eugene Kuzmenko

0

Benim için daha kolay olduğu için öğrendiğim bu yöntemi kullanıyorum. Fonksiyon bileşeni ile birlikte kullanıyorum. Bunu yalnızca, kullanıcı sayfanızdaki Javascript'i devre dışı bırakırsa herhangi bir başlık görüntülenmemesini istemiyorsanız yapın.

Yapmanız gereken iki şey var.

1. index.html dosyanıza gidin ve bu satırı buradan silin

<title>React App</title>

2. mainapp işlevinize gidin ve normal bir html yapısı olan bunu geri döndürün, ana içeriğinizi web sitenizden gövde etiketleri arasına kopyalayıp yapıştırabilirsiniz:

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

Başlığı dilediğiniz gibi değiştirebilirsiniz.


-8

Yeni başlayan biriyseniz, react proje klasörünüzün ortak klasörüne gidip "index.html" içinde başlığı düzenleyip kendi başlığınızı koyarak kendinizi tüm bunlardan kurtarabilirsiniz. Yansıtması için kaydetmeyi unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.