๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

react

React / Router ์‹ค์Šต - ๋™๋ฌผ ์ •๋ณด ์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ

๊ธฐ๋Šฅ ๋ชฉ๋ก

  • ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ๋™๋ฌผ ๋ชฉ๋ก ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ
  • ๋™๋ฌผ ์ƒ์„ธ ์ •๋ณด ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ
  • ๋™๋ฌผ ์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ & ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

 

์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ

main.jsx
โŽฟ  app.jsx
    โŽฟ  Main.jsx
    โŽฟ  Detail.jsx
    โŽฟ  Search.jsx

 

 

 


 

 

1. ๋™๋ฌผ ๋ชฉ๋ก์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ

main.jsx

React Router๋ฅผ ์•ฑ ์ „์ฒด์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ App ์ปดํฌ๋„ŒํŠธ๋ฅผ BrowserRouter ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ์‹ธ๊ณ  ์žˆ๋‹ค.

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>,
);

 

 

App.jsx

๊ฐ๊ฐ์˜ Route์—์„œ๋Š” ๊ฐ ํŽ˜์ด์ง€์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์š”์†Œ๋กœ ๋ถˆ๋Ÿฌ์™€ ๋ถ„๊ธฐ๋ณ„๋กœ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋„๋ก ํ•˜๊ณ ,

Routes๋Š” ์ด Route๋“ค์„ ๋ฌถ์–ด์ฃผ๊ณ  ์žˆ๋‹ค.

 

์ด๋•Œ Detail ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ƒ์„ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๊ฐ ํŽ˜์ด์ง€์—์„œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๊ณ ์œ ํ•œ id๊ฐ’์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ๋ถˆ๋Ÿฌ์˜ฌ ๋ฐ์ดํ„ฐ๋“ค์€ ๋ชจ๋‘ ๊ณ ์œ ํ•œ id๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋ฐ์ดํ„ฐ๋“ค์€ data.js ํŒŒ์ผ ๋‚ด์— ๋‹ด๊ฒจ์žˆ๋Š”๋ฐ, data.js๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

๋”๋ณด๊ธฐ

data.js์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ‚ค:๊ฐ’์˜ ์Œ๋“ค๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ์ฒด์˜ ๋ฐฐ์—ด๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. (์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ฐฐ์—ด์˜ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.)

์ด๋•Œ images๋Š” images์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ์ž„ํฌํŠธ๋œ ํŒŒ์ผ์˜ ๋ณ€์ˆ˜๋‹ค.

{
    id:8,
    name:'ํŒ๋‹ค',
    img: images.panda,
    description: 'ํŒ๋‹ค๋Š” ์œ ์ „ํ•™์ ์œผ๋กœ ์œก์‹๋™๋ฌผ์— ๊ฐ€๊น๋‹ค.'
},

 

๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ(Path Parameter)๋ž€ URL์˜ ๊ฒฝ๋กœ ์ผ๋ถ€๋กœ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ด๋ฅผ ์‚ฌ์šฉํ•ด URL์—์„œ id ๊ฐ’์„ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, id์˜ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ธ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

function App() {
  return (
    <>
      <header>
        <h1>๐Ÿ’š ๋™๋ฌผ ์กฐ์•„ ๐Ÿ’š</h1>
      </header>
      <Routes>
        <Route path="/" element={<Main />}></Route>
        <Route path="/detail/:id" element={<Detail />}></Route>
        <Route path="/search" element={<Search />}></Route>
      </Routes>
      <footer>all rights reserved to OZ</footer>
    </>
  );
}

 

 

Main.jsx

data์˜ ๊ฐ ๊ฐ’์„ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐฐ์—ดํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— map์œผ๋กœ ๊ฐ’๋“ค์„ ๊ฐ๊ฐ <li> ์š”์†Œ์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

function Main() {
  return (
    <ul>
      {data.map((el) => (
        <li key={el.id}>
          <Link to={`/detail/${el.id}`}>
            <img src={el.img}></img>
            <div>{el.name}</div>
          </Link>
        </li>
      ))}
    </ul>
  );
}

 

data์˜ ๊ฐ ์š”์†Œ๊ฐ€ el์ด๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋“ค์–ด์™€์„œ map ํ•จ์ˆ˜๋กœ ๋ฐ˜ํ™˜๋˜๊ณ  ์žˆ๋‹ค.

key ์†์„ฑ์€ el.id๊ฐ’์œผ๋กœ ๋ถ€์—ฌํ–ˆ๊ณ , ํ•ญ๋ชฉ์˜ ์ด๋ฏธ์ง€์™€ ์ด๋ฆ„๋„ el.img, el.name์œผ๋กœ ๋ฐ›์•„์˜ค๊ณ  ์žˆ๋‹ค.

 

ํ•ด๋‹น liํƒœ๊ทธ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๊ทธ ์ƒ์„ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— Link ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ์‹ธ์ฃผ๊ณ  ์žˆ๋Š”๋ฐ,

Link์˜ to ์†์„ฑ์€ /detail/:id'๋กœ :id๋ฅผ ๊ฒฝ๋กœ ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์™€ ๊ณ ์œ ํ•œ id๊ฐ’์„ ๊ฐ€์ง„ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ์žˆ๋‹ค.

 

 

์ง€๊ธˆ๊นŒ์ง€์˜ ๋ Œ๋”๋ง๋˜๋Š” ํ™”๋ฉด

 


 

 

2. ๋™๋ฌผ ์ƒ์„ธ ์ •๋ณด ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

Detail.jsx

Main.jsx์—์„œ ๋™๋ฌผ ์นด๋“œ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, Link ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋™ํ•˜๋ฉด์„œ el.id๋ฅผ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธฐ๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋ฅผ UseParams()์„ ์‚ฌ์šฉํ•ด ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

useParams()์€ URL ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ผ์šฐํ„ฐ์˜ Hook ์ค‘ ํ•˜๋‚˜๋กœ,

์œ„์˜ App.jsx์—์„œ Route ์ปดํฌ๋„ŒํŠธ์—์„œ ๋™์ผํ•œ ํ˜•์‹()์œผ๋กœ ์ง€์ •ํ•ด๋†จ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฌธ์ œ์—†์ด ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. 

 

์˜ˆ๋ฅผ ๋“ค์–ด id๊ฐ€ 3๋ฒˆ์ธ ์นด๋“œ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, const params = useParams();์œผ๋กœ ๊ฒฝ๋กœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ params๋ผ๋Š” ๋ณ€์ˆ˜์— ๋‹ด๊ณ  ์ด๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ์ถœ๋ ฅ๋œ๋‹ค.

 

function Detail() {
  const params = useParams();
  const animalData = data.find((el) => el.id === Number(params.id));

  return (
    <section className="detail">
      <img src={animalData.img} />
      <h2>{animalData.name}</h2>
      <div>{animalData.description}</div>
    </section>
  );
}

 

ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ๊ฐ€์ ธ์™”๊ณ  ์ด์ œ ์ด ์•„์ด๋””์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ find()๋ฅผ ์‚ฌ์šฉํ•ด ํ•ด๋‹น id๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ณ€์ˆ˜ animalData์— ์ €์žฅํ•œ๋‹ค.
find() : ์ฒซ๋ฒˆ์งธ๋กœ ์กฐ๊ฑด์— ๋งž๋Š” ๋‹จ์ผ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (์—†์„ ๊ฒฝ์šฐ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

์ด๋•Œ useParams()์€ ๋ชจ๋“  ๊ฐ’์„ stringํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ el.id === params.id๋ฅผ ํ•  ๊ฒฝ์šฐ undefined๊ฐ€ ๋‚˜์˜จ๋‹ค. ๊ทธ๋ž˜์„œ Number()๋กœ params.id๋ฅผ ์ˆซ์ž ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์ค˜์„œ ๋น„๊ตํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ id๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

 

์ƒ์„ธ ํŽ˜์ด์ง€ ํ™”๋ฉด, ์ฃผ์†Œ๋Š” http://localhost:5173/detail/8

 

 

 


 

 

3. ๋™๋ฌผ ์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ & ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ํŽ˜์ด์ง€ ์ƒ์„ฑํ•˜๊ธฐ

App.jsx

์ด๋ฒˆ ๊ฒฝ์šฐ์—๋Š” ์œ„์˜ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ์™€๋Š” ๋‹ฌ๋ฆฌ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์˜ ์ •๋ณด๋กœ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•ด ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์€ URL์˜ ๋์— ?key=value ํ˜•ํƒœ๋กœ ๋ถ™๋Š” ์ถ”๊ฐ€ ์ •๋ณด๋กœ, ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฌ๋Ÿฌ ์Œ์ผ ๊ฒฝ์šฐ &๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค.

์ฃผ๋กœ ๊ฒ€์ƒ‰ ์กฐ๊ฑด, ํ•„ํ„ฐ ๋“ฑ์„ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด ๊ฒฝ์šฐ์—๋Š” ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์ „๋‹ฌํ•˜๊ณ  ์žˆ๋‹ค.

 

function App() {
  const [inputValue, setInputValue] = useState('');
  const navigate = useNavigate();
  return (
    <>
      <header>
        <h1>๐Ÿ’š ๋™๋ฌผ ์กฐ์•„ ๐Ÿ’š</h1>
        <input
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
        <button onClick={() => navigate(`/search?animal=${inputValue}`)}>
          ๊ฒ€์ƒ‰
        </button>
      </header>
      <Routes>
        <Route path="/" element={<Main />}></Route>
        <Route path="/detail/:id" element={<Detail />}></Route>
        <Route path="/search" element={<Search />}></Route>
      </Routes>
      <footer>all rights reserved to OZ</footer>
    </>
  );
}

 

๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ๊ฐ€์ง„ URL๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋จผ์ € useNavigate()๋กœ ํŽ˜์ด์ง€ ์ด๋™์„ ์œ„ํ•œ ํ•จ์ˆ˜ navigate๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

input์—๋Š” ๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ์ž…๋ ฅ๋ฐ›์€ ๊ฒ€์ƒ‰์–ด๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด navigate ํ•จ์ˆ˜๋กœ ์•ˆ์— ์ง€์ •๋œ ๊ฒฝ๋กœ๋กœ ์ด๋™๋œ๋‹ค.

 

์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๋‹ฌ๋ฆฌ Route ์ปดํฌ๋„ŒํŠธ์— ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ง๊ทธ๋Œ€๋กœ ๊ฒฝ๋กœ ์•ˆ์— ํฌํ•จ๋œ ๋ณ€์ˆ˜๊ณ , ์ด ์•ˆ์— ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด์„œ ๋ผ์šฐํ„ฐ๊ฐ€ ์ง์ ‘ ํ•ด์„ํ•˜๋Š” ๊ฑฐ๋ผ๋ฉด

์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์€ ๊ฒฝ๋กœ์— ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์ด ๋ถ™์—ฌ์ง„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์šฐํ„ฐ๋Š” ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์„ ๋ฌด์‹œํ•˜๊ณ  Search ์ปดํฌ๋„ŒํŠธ๋งŒ ๋ณด์—ฌ์ค€๋‹ค.

 

ํ•ญ๋ชฉ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง
๋ผ์šฐํ„ฐ๊ฐ€ ํ•ด์„ O X (URL์˜ ์ผ๋ถ€๋กœ ๋ฌด์‹œ๋จ)
์‚ฌ์šฉ ์ด์œ  ๊ณ ์œ ํ•œ ๋ฐ์ดํ„ฐ ์‹๋ณ„ ์กฐ๊ฑด ์ „๋‹ฌ (๊ฒ€์ƒ‰, ํ•„ํ„ฐ, ์ •๋ ฌ ๋“ฑ)
ํ˜•์‹ /๊ฒฝ๋กœ/ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’ /๊ฒฝ๋กœ?ํ‚ค=๊ฐ’
์ปดํฌ๋„ŒํŠธ์™€์˜ ๋งค์นญ ์—ฌ๋ถ€ /๊ฒฝ๋กœ/ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋ฆ„ ๊ณผ ์ผ์น˜ํ•ด์•ผํ•จ /๊ฒฝ๋กœ ๋งŒ ์ผ์น˜ํ•˜๋ฉด ๋จ
์ ‘๊ทผ ๋ฐฉ์‹ useParams().ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋ฆ„ useSearchParams().get('ํ‚ค')

 

 

Search.jsx

๊ฒ€์ƒ‰ํ•  ๋•Œ ๋ฌธ์ž์—ด์˜ ํŒจํ„ด์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ •๊ทœ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€๋ฐ, ํ•œ๊ธ€๋กœ ๊ฒ€์ƒ‰ํ•  ๋•Œ korean-regexp ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

korean-regexp๋Š” ํ•œ๊ตญ์–ด ์ •๊ทœ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

ํ•œ๊ธ€์„ ๊ธฐ์ค€์œผ๋กœ ๋งŒ๋“  ๊ฒƒ์ด๋ผ ์ดˆ์„ฑ/์ค‘์„ฑ/์ข…์„ฑ์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ์„ฑ์ด๋‚˜ ๋ชจ์Œ๋งŒ ์žˆ์–ด๋„ ๊ฒ€์ƒ‰์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

npm i korean-regexp

 

 

navigate()๋กœ ๋„˜์–ด๊ฐ„ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์˜ ๊ฐ’์„ useSearchParams()๋กœ ์ฝ์–ด์™”๋‹ค.

์ด๋•Œ useSearchParams()์€ [๊ฐ์ฒด, ๊ฐ์ฒด ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜]๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” ๊ฒ€์ƒ‰์–ด๋กœ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋Š” ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด๋งŒ ๊ฐ€์ ธ์™€์„œ ์ƒ์„ฑํ–ˆ๋‹ค.

์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์˜ ํ‚ค์ธ animal์˜ ๊ฐ’(๊ฒ€์ƒ‰์–ด)์„ param์ด๋ผ๋Š” ๋ณ€์ˆ˜์— ๋‹ด์•˜๊ณ , reg ๋ณ€์ˆ˜๋Š” param์„ ์ดˆ์„ฑ์—๋„ ๋งค์น˜๋  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ง„ ์ •๊ทœ์‹ ๊ฐ์ฒด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ ํ•„ํ„ฐ๋ง๋œ ๋ฐ์ดํ„ฐ๋ฅผ data์— filter ๋ฉ”์„œ๋“œ๋กœ ํ•„ํ„ฐ๋งํ•ด ์กฐ๊ฑด์— ๋งž๋Š” ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค.

์ด ๋•Œ match()๋Š” ๋ฌธ์ž์—ด์ด ์ •๊ทœ์‹๊ณผ ์ผ์น˜ํ•˜๋ฉด, ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž์—ด์„ ํ‡๋งˆํ•˜๋Š” array๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋‹ค.

 

import { Link, useSearchParams } from 'react-router-dom';
import { data } from '../assets/data/data';
import { getRegExp } from 'korean-regexp';

function Search() {
  const [searchParams] = useSearchParams();
  const param = searchParams.get('animal');
  const reg = getRegExp(param);
  // ๋ฌธ์ž์—ด์˜ ํŒจํ„ด์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ •๊ทœ์‹์„ ์‚ฌ์šฉ
  const filteredData = data.filter((el) => el.name.match(reg));

  return (
    <ul>
      {filteredData.map((el) => (
        <li key={el.id}>
          <Link to={`/detail/${el.id}`}>
            <img src={el.img}></img>
            <div>{el.name}</div>
          </Link>
        </li>
      ))}
    </ul>
  );
}

export default Search;

 

 

ํ•œ๊ธ€ ์ •๊ทœ์‹์„ ์‚ฌ์šฉํ•ด์„œ ์ดˆ์„ฑ๋งŒ ์ž‘์„ฑํ•ด๋„ ใ…๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํŒ๋‹ค, ํŽญ๊ท„์ด ํ‘œ์‹œ๋˜๊ณ  ์žˆ๋‹ค.

 

 

+ ใ…ใ„ท๋กœ ๊ฒ€์ƒ‰ํ–ˆ์„ ๋•Œ ํŒ๋‹ค๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

ใ…๋กœ ๊ฒ€์ƒ‰ํ•˜๋ฉด ํŒ๋‹ค๋ž‘ ํŽญ๊ท„์ด ์ž˜ ๋‚˜์˜ค๋Š”๋ฐ, ์ด๋Š” 'ใ…'์ด ๋‹จ์–ด์˜ ์ดˆ์„ฑ์œผ๋กœ ์žˆ์„ ๋•Œ์˜ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•ด์ฃผ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ใ…๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋‹จ์–ด๋Š” ๋‹ค ํฌํ•จํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ใ…ใ„ท๋กœ ๊ฒ€์ƒ‰ํ•  ๊ฒฝ์šฐ 'ใ…ใ„ท'๋ฅผ ์ดˆ์„ฑ์„ ๋‚˜์—ดํ•œ ๋ฌธ์ž์—ด๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ดˆ์„ฑ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ๋œ๋‹ค.

 

๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•œ๋ฐ, reg๋ฅผ ์„ ์–ธํ•  ๋•Œ { initialSearch:true}๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค

  const reg = getRegExp(param, { initialSearch: true });