Skip to content

πŸ‘‘ React-Helmet-Async 라이브러리λ₯Ό μ΄μš©ν•˜μ—¬ λ§Œλ“  μ˜ˆμ œμž…λ‹ˆλ‹€.

Notifications You must be signed in to change notification settings

light9639/React-Helmet-TypeScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ‘‘ React-Helmet-Async 라이브러리λ₯Ό μ΄μš©ν•˜μ—¬ λ§Œλ“  μ˜ˆμ œμž…λ‹ˆλ‹€.

:octocat: λ°”λ‘œκ°€κΈ° : https://light9639.github.io/React-Helmet-TypeScript/

Img

✨ React-Helmet-Async 라이브러리λ₯Ό μ΄μš©ν•˜μ—¬ λ§Œλ“  μ˜ˆμ œμž…λ‹ˆλ‹€. ✨

πŸŽ‰ React ν”„λ‘œμ νŠΈ 생성

  • React 생성
npm create-react-app my-app
# or
yarn create react-app my-app
  • viteλ₯Ό μ΄μš©ν•˜μ—¬ ν”„λ‘œμ νŠΈλ₯Ό μƒμ„±ν•˜λ €λ©΄
npm create vite@latest
# or
yarn create vite
  • ν„°λ―Έλ„μ—μ„œ μ‹€ν–‰ ν›„ ν”„λ‘œμ νŠΈ 이름 λ§Œλ“  ν›„ React 선택, Typescirpt-SWC μ„ νƒν•˜λ©΄ 생성 μ™„λ£Œ.

πŸš‚ react-helmet-async, sass, react-router-dom μ„€μΉ˜

  • 이 ν”„λ‘œμ νŠΈλ₯Ό λ§Œλ“€λ €λ©΄ ν•„μš”ν•œ μ—¬λŸ¬ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ„ μ„€μΉ˜ν•΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ react-helmet-async, sass, react-router-dom을 μ„€μΉ˜ν•œλ‹€.
$ npm install react-helmet-async sass react-router-dom
# or
$ yarn add react-helmet-async sass react-router-dom

βœ’οΈ main.tsx, App.tsx, index.scss, App.scss μˆ˜μ • 및 μž‘μ„±

⚑ main.tsx

  • react-router-domμ—μ„œ BrowserRouter을 importν•œ λ’€ App μ»΄ν¬λ„ŒνŠΈλ₯Ό κ°μ‹Έμ„œ λΌμš°νŒ… κΈ°λŠ₯을 μΆ”κ°€ν•œλ‹€.
import { BrowserRouter } from 'react-router-dom'

<BrowserRouter>
  <App />
</BrowserRouter>

⚑ App.tsx

  • react-helmet-asyncλ₯Ό μ΄μš©ν•˜μ—¬ link, title을 μž‘μ„±ν•˜κ³  Hello.tsx둜 propsλ₯Ό μ „μ†‘ν•˜μ—¬ titleλͺ…이 λ°”λ€Œλ„λ‘ μ„€μ •ν•œλ‹€.
  • react-router-dom의 Link, Routes, Route을 μ΄μš©ν•˜μ—¬ λΌμš°νŒ… κΈ°λŠ₯ κ΅¬ν˜„.
  • λ¬Έμ„œ 상단에 Header μ»΄ν¬λ„ŒνŠΈλ₯Ό λ„£μ–΄μ„œ Linkλ₯Ό 톡해 νŽ˜μ΄μ§€ 이동 μ‹œν‚€κ²Œ ν•œλ‹€.
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import HelmetImg from './assets/Helmet.png'
import { Helmet, HelmetProvider } from "react-helmet-async";
import Hello from "./components/Hello";
import Detail from "./components/Detail";
import { Link, Routes, Route } from 'react-router-dom'
import Header from './components/Header';
import './App.scss'

export default function App(): JSX.Element {
  return (
    <div className="App">
      <Header />
      <div>
        <a href="https://www.npmjs.com/package/react-helmet-async" target="_blank">
          <img src={HelmetImg} className="logo" alt="Helmet logo" />
        </a>
        <a href="https://reactjs.org" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <HelmetProvider>
        <div>
          <Helmet>
            <link rel="icon" type="image/svg+xml" href={HelmetImg} />
            <title>React-Helmet-Async</title>
            <link rel="canonical" href="https://www.tacobell.com/" />
          </Helmet>
          <Routes>
            <Route path="/" element={<Hello name="React-Helmet-Async" />} />
            <Route path="/detail/:id" element={<Detail name="Detail" />} />
            <Route path="*" element={<Hello name="This is Error Page" />} />
          </Routes>
          <h2>링크λ₯Ό ν΄λ¦­ν•˜λ©΄ 이름과 Titleλͺ…이 λ³€κ²½λ©λ‹ˆλ‹€. {"\u2728"}</h2>
        </div>
      </HelmetProvider>
    </div>
  )
}

⚑ index.scss

  • index.scss에 @mixin을 μ΄μš©ν•œ λ°˜μ‘ν˜• ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•œλ‹€.
@mixin mobile {
  @media (max-width: 767px) {
    @content;
  }
}

h1 {
  font-size: 1.75rem;
  line-height: 1.1;

  @include mobile {
    font-size: 1.35rem;
  }
}

h2 {
  margin-top: 30px;
  font-size: 1.1rem;

  @include mobile {
    margin-top: 25px;
    font-size: 0.9rem;
  }
}

⚑ App.scss

  • App.scss에 @mixin을 μ΄μš©ν•œ λ°˜μ‘ν˜• ν•¨μˆ˜μ™€, Header 뢀뢄에 μŠ€νƒ€μΌλ§μ„ μΆ”κ°€ν•œλ‹€.
  • logo ν˜Έλ²„μ‹œ νš¨κ³Όμ™€ λ°˜μ‘ν˜• μŠ€νƒ€μΌλ§ μΆ”κ°€.
@mixin mobile {
  @media (max-width: 767px) {
    @content;
  }
}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
  margin: 75px 0 30px;

  @include mobile {
    height: 5rem;
    margin: 60px 0 10px;
  }

  &:hover {
    filter: drop-shadow(0 0 2em #61dafbaa);
  }

  &.react:hover {
    filter: drop-shadow(0 0 2em #61dafbaa);
  }
}

.Header {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  margin-bottom: 25px;
  gap: 25px;
  background-color: #000;
  width: 100%;
  padding: 20px 0;

  @include mobile {
    flex-wrap: wrap;
  }

  a {
    font-size: 1rem;
    color: #fff;
    font-weight: 600;
    transition: .5s;

    @include mobile {
      font-size: 0.9rem;
    }

    &:hover,
    &:focus {
      color: skyblue;
    }
  }
}

πŸ“ components 파일 속 Detail.tsx, Header.tsx, Hello.tsx μˆ˜μ • 및 μž‘μ„±

⚑ Detail.tsx

  • App.tsxμ—μ„œ <Route path="/detail/:id />λ₯Ό μ‚¬μš©ν•˜μ—¬ /detail/2둜 μ΄λ™μ‹œ title이 Detail2 Page이 λ˜λ„λ‘ μ„€μ •ν•œλ‹€.
  • useParams()λ₯Ό μ‚¬μš©ν•˜μ—¬ 각 νŽ˜μ΄μ§€λ§ˆλ‹€μ˜ μˆ«μžκ°’μ„ κ°€μ Έμ˜¨ ν›„ ν…μŠ€νŠΈμ™€ title 값에 λ„£λŠ”λ‹€.
import * as React from "react";
import { useParams } from 'react-router-dom';
import { Helmet, HelmetProvider } from "react-helmet-async";

interface Props {
    name: string;
}

export default ({ name }: Props) => {
    let { id } = useParams();
    console.log(id)

    return (
        <React.Fragment>
            <Helmet>
                <title>{name}{id} Page</title>
            </Helmet>
            <h1>Hello {name} {id}!</h1>
        </React.Fragment>
    )
}

⚑ Header.tsx

  • 상단에 Header μ»΄ν¬λ„ŒνŠΈλ₯Ό λ„£μ–΄μ„œ Linkλ₯Ό 톡해 νŽ˜μ΄μ§€ 이동을 κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€.
import React from 'react'
import { Link } from 'react-router-dom'

export default function Header(): JSX.Element {
    return (
        <div className='Header'>
            <Link to="/">Home</Link>
            <Link to="/detail/1">Detail1</Link>
            <Link to="/detail/2">Detail2</Link>
            <Link to="/detail/3">Detail3</Link>
            <Link to="Error">Error</Link>
        </div>
    )
}

⚑ Hello.tsx

  • App.tsxμ—μ„œ props둜 전달받은 값듀이 titleλͺ…에 μ „λ‹¬λ˜λ„λ‘ λ§Œλ“€κ³  h1 νƒœκ·Έ μ•ˆμ—λ„ 듀어가도둝 μ„€μ •ν•œλ‹€.
import * as React from "react";
import { useParams } from 'react-router-dom';
import { Helmet } from "react-helmet-async";

interface Props {
    name: string;
}

export default ({ name }: Props) => {
    return (
        <React.Fragment>
            <Helmet>
                <title>{name} Page</title>
            </Helmet>
            <h1>Hello {name}</h1>
        </React.Fragment>
    )
}

πŸ“Ž 좜처

About

πŸ‘‘ React-Helmet-Async 라이브러리λ₯Ό μ΄μš©ν•˜μ—¬ λ§Œλ“  μ˜ˆμ œμž…λ‹ˆλ‹€.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published