느려도 한걸음씩

Props를 좀 더 유연하게 다루는 방법 본문

FE develop/React

Props를 좀 더 유연하게 다루는 방법

hoj0806 2024. 3. 28. 20:24



리액트에서 props를 좀더 유연하게 다뤄보자

 

import { EXAMPLES } from "../data";
import TabButton from "./TabButton";
import { useState } from "react";
import Section from "./Section";
import Tabs from "./Tabs";
export default function Examples() {
  const [selectedTopic, setSelectedTopic] = useState();
  let tabContent = <p>Please select a topic.</p>;
  if (selectedTopic) {
    tabContent = (
      <div id='tab-content'>
        <h3>{EXAMPLES[selectedTopic].title}</h3>
        <p>{EXAMPLES[selectedTopic].description}</p>
        <pre>
          <code>{EXAMPLES[selectedTopic].code}</code>
        </pre>
      </div>
    );
  }
  function handleSelect(selectedButton) {
    setSelectedTopic(selectedButton);
  }
  return (
    <Section title='Examples' id='examples'>
      <Tabs
        buttons={
          <>
            <TabButton
              isSelected={selectedTopic === "Components"}
              onClick={() => handleSelect("Components")}
            >
              Components
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "JSX"}
              onClick={() => handleSelect("JSX")}
            >
              JSX
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "Props"}
              onClick={() => handleSelect("Props")}
            >
              Props
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "State"}
              onClick={() => handleSelect("State")}
            >
              State
            </TabButton>
          </>
        }
      >
        {tabContent}
      </Tabs>
    </Section>
  );
}

 

export default function Tabs({ children, buttons, ButtonsContainer = "menu" }) {
  return (
    <>
      <ButtonsContainer>{buttons}</ButtonsContainer>
      {children}
    </>
  );
}

 

현재 Tabs 컴포넌트에 children, buttons, ButtonsContainer 3가지 props를 전달하고 있다

children은 커스텀 컴포넌트의 태그 사이에 들어갈 내용을 정의할수 있는 props이다

buttons는 JSX 요소를 자바스크립트 표현식을 통해서 props를 보내고 있다 이렇게 적어주면 JSX 요소를 그대로 props로
보내 해당 컴포넌트의 원하는 자리에 위치시킬수 있다

 

마지막으로 ButtonsContainer의 경우 menu라는 string값을 default값으로 받고있다 이렇게 작성해주면 ButtonsContainer라는 이름으로 menu라는 내장태그가 적용된다 만약 ButtonsContainer라는 이름으로 div태그를 만들고 싶으면 



export default function Tabs({ children, buttons, ButtonsContainer = "div" }) {
  return (
    <>
      <ButtonsContainer>{buttons}</ButtonsContainer>
      {children}
    </>
  );
}


이렇게 작성해주면 된다 그리고 중요한 점은 태그 이름을 props로 보낼때는 맨 앞글자를 대문자로 작성해 리액트가 컴포넌트라고 인식하게 만들어줘야한다

 

 

 

만약 내장태그아 아닌 본인이 정의한 다른 컴포넌트를 태그로 하고 싶다면 JSX를 props로 보내준것처럼 표현식을 이용해야한다

 

 ButtonsContainer={Section}

 

import { EXAMPLES } from "../data";
import TabButton from "./TabButton";
import { useState } from "react";
import Section from "./Section";
import Tabs from "./Tabs";
export default function Examples() {
  const [selectedTopic, setSelectedTopic] = useState();
  let tabContent = <p>Please select a topic.</p>;
  if (selectedTopic) {
    tabContent = (
      <div id='tab-content'>
        <h3>{EXAMPLES[selectedTopic].title}</h3>
        <p>{EXAMPLES[selectedTopic].description}</p>
        <pre>
          <code>{EXAMPLES[selectedTopic].code}</code>
        </pre>
      </div>
    );
  }
  function handleSelect(selectedButton) {
    setSelectedTopic(selectedButton);
  }
  return (
    <Section title='Examples' id='examples'>
      <Tabs
        ButtonsContainer={Section}
        buttons={
          <>
            <TabButton
              isSelected={selectedTopic === "Components"}
              onClick={() => handleSelect("Components")}
            >
              Components
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "JSX"}
              onClick={() => handleSelect("JSX")}
            >
              JSX
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "Props"}
              onClick={() => handleSelect("Props")}
            >
              Props
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "State"}
              onClick={() => handleSelect("State")}
            >
              State
            </TabButton>
          </>
        }
      >
        {tabContent}
      </Tabs>
    </Section>
  );
}