본문 바로가기

Libraries/React

[React] 공통 컴포넌트 세팅, 버튼 만들기 (onClick, props), 컴포넌트 사용 (emotion diary 프로젝트 1탄)

728x90

 

 

아래와 같은 공통 컴포넌트 버튼을 만들 것이다.


 

 


 

 

 1. src/components 폴더 안에 MyButton.js 라는 파일(컴포넌트)을 생성한다. 

 

 

 

 

 2. MyButton.js의 기본 구조를 작성한다. 

 

 MyButton.js 

const MyButton = () => {
 return(
   <button></button>
    )
  };
  
  export default MyButton;

 

 

 

 3. props로 text, type, onCilck을 받는다. 

 

 MyButton.js 

const MyButton = ({ text, type, onClick }) => {
 return(
   <button></button>
    )
  };
  
  export default MyButton;

 

 

 

 4. button에 props를 연결한다. 

 

 MyButton.js 

const MyButton = ({ text, type, onClick }) => {
 return(
   <button className={"MyButton"} onClick={onClick}>
      {text}
   </button>
    )
  };
  
  export default MyButton;

 

 

 

 

 5. App.js에서 MyButton 컴포넌트를 import 한다. 

 

 App.js 

import MyButton from "./components/MyButton";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
     <MyButton />
    </div>
  );
}

 

 

 

 

 6. <MyButton />에 props를 전달한다. 

 

 App.js 

import MyButton from "./components/MyButton";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
     <MyButton text={"버튼"} onClick={()=>alert("버튼 클릭")} type={"positive"}/>
    </div>
  );
}

 

 

버튼을 클릭하면 alert창이 뜬다.

 

 

 

 7. 버튼을 스타일링한다. 

 

 styles.css 

.MyButton{
  cursor: pointer;
  border: none;
  border-radius: 5px;
  padding: 10px 20px 10px 20px;
  font-size: 18px;
  white-space: nowrap;
  font-family: "Nanum Pen Script";
}

 

 

 

 

 8. type prop의 값을 설정한다. 

 

App 컴포넌트에서 MyButton의 type이 positive인데, 회색버튼으로 나오므로, type에 따라서 3가지로 나오게 만들어야함.

 

 App.js 

import MyButton from "./components/MyButton";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
     <MyButton text={"버튼"} onClick={()=>alert("버튼 클릭")} type={"positive"}/> //positive로 설정 돼있음
    </div>
  );
}

 

 

MyButton에서 type prop을 전달하지 않으면 default로 전달하게끔 하기

 MyButton.js 

const MyButton = ({ text, type, onClick }) => {
  return(
    <button className={"MyButton"} onClick={onClick}>
       {text}
    </button>
     )
   };

   MyButton.defaultProps = {   // default 값
     type: "default"
   }
   
   export default MyButton;

 

 

 

 9. 클래스 네임을 type에 따라 동적으로 설정한다.

 

className을 배열로 구성해서, 바뀌는 항목(type)을 템퍼릿리터럴 방식으로 사용해서 만든다. 

 MyButton.js 

const MyButton = ({ text, type, onClick }) => {
  return(
    <button className={["MyButton", `MyButton_${type}`]} onClick={onClick}>
       {text}
    </button>
     )
   };

   MyButton.defaultProps = {
     type: "default"
   }
   
   export default MyButton;

 

 

그런데 className은 배열로 전달하는게 아니라, 문자열로 전달해야해서 배열을 join 메서드를 이용해 띄어쓰기를 separater로 해서 합쳐준다.

 MyButton.js 

const MyButton = ({ text, type, onClick }) => {
  return(
    <button className={["MyButton", `MyButton_${type}`].join(" ")} onClick={onClick}>
       {text}
    </button>
     )
   };

   MyButton.defaultProps = {
     type: "default"
   }
   
   export default MyButton;

 

이렇게 되면 type이 전달됐을 때, 클래스네임이 아래와 같이 지정된다.

MyButton MyButton_positive
MyButton MyButton_negative
MyButton MyButton_default

 

 

 

 10. negative와 default 버튼도 만든다. 

 

 App.js 

import MyButton from "./components/MyButton";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"positive"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"negative"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"default"}
      />
    </div>
  );
}

 

 

 

 

 11. CSS에서 type에 따라 색 다 다르게 적용시키기 

 

 styles.css 

.MyButton{
  cursor: pointer;
  border: none;
  border-radius: 5px;
  padding: 10px 20px 10px 20px;
  font-size: 18px;
  white-space: nowrap;
  font-family: "Nanum Pen Script";
}

.MyButton_default{   /* default 값 */
  background-color: #ececec;
  color: black;
}

.MyButton_positive{  /* positive 값 */
  background-color: #64c964;
  color: white;
}

.MyButton_negative{  /* negative 값 */
  background-color: #fd565f;
  color: white;
}

 

 

 

 

 12. 템플릿 리터럴(Template literal) 수정하기 

 

MyButton에서 템플릿 리터럴로 활용하게 하면
type에 임의의 글자를 넣어버렸을 때 다른 의도하지 않았던 버튼이 나올 수도 있기 때문에, 조건을 달아줘야한다.

includes 메서드를 사용해 positive나 negative type이 있으면 type 그대로를 반환하고, 없다면 default를 반환하게 만든다.

이렇게 하면 이상한 글자를 치더라도 default로 바껴서 들어오게된다.

템플릿 리터럴 안에 내용은  `MyButton_${btnType}` 로 변경하면 된다.

 

const MyButton = ({ text, type, onClick }) => {
  
  const btnType = ['positive', 'negative'].includes(type)? type : 'default'  // 조건문 생성
  
  return(
    <button className={["MyButton", `MyButton_${btnType}`].join(" ")} onClick={onClick}>
       {text}
    </button>
     )
   };

   MyButton.defaultProps = {
     type: "default"
   }
   
   export default MyButton;

 

 

 

13. 버튼 컴포넌트를 다른 컴포넌트(헤더 컴포넌트) 안에서 써보기 

 

내가 만들 페이지들은 페이지 별로 이러한 헤더들을 갖게 된다.

 

 

이 헤더들은 아래와 같은 공통점이 보인다.

 

 

3개의 props에 따라 각각 다르게 동작하게 만들면 된다.

 

 

 

 14. 헤더 컴포넌트 만들기 

 

 MyHeader.js 

const MyHeader = () => {
  return <header></header>
}

export default MyHeader;

 

 

 

 15. 헤더 컴포넌트는 props로 3개를 받음 

 

 MyHeader.js 

const MyHeader = ({headText, leftChild, rightChild}) => {
  return <header></header>
}

export default MyHeader;

 

 

 

 16. className 지정하고 내용 넣기 

 

 MyHeader.js 

const MyHeader = ({headText, leftChild, rightChild}) =>{
  return <header>
  <div className="head_btn_left">
    {leftChild}
  </div>
  <div className="head_text">
    {headText}
  </div>
  <div className="head_btn_right">
    {rightChild}
  </div>
  </header>
}

export default MyHeader;

 

 

 

 17. App.js에서 헤더 컴포넌트 불러오고 headText 넣기 

 

 App.js 

import MyButton from "./components/MyButton";
import MyHeader from './components/MyHeader';  // import 하기

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <MyHeader headText={"헤더"} /> // 컴포넌트 불러오고 내용 넣기
      <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"positive"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"negative"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"default"}
      />
    </div>
  );
}

 

 

 

 

 18. 헤더 컴포넌트 스타일링 하기 

 

/* HEADER */

header{
  padding-top: 20px;
  padding-bottom: 20px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #e2e2e2;
}

header > div {
  display: flex;
}

header .head_text{
  width: 50%;
  font-size: 25px;
  justify-content: center;
}

header .head_btn_left{
  width: 25%;
  justify-content: start;
}

header .head_btn_right{
  width: 25%;
  justify-content: end;
}

header button{
  font-family: "Nanum Pen Script";
}

 

 

 

 

 19. leftChild(왼쪽버튼)와 rightChild(오른쪽 버튼) 넣기 

 

import MyButton from "./components/MyButton";
import MyHeader from './components/MyHeader';

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <MyHeader 
        headText={"헤더"}  
        leftChild={<MyButton text={'왼쪽 버튼'} onClick={()=>alert("왼쪽 클릭")}/>}  
        rightChild={<MyButton text={'오른쪽 버튼'} onClick={()=>alert("오른쪽 클릭")}/>}/>
     
     <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"positive"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"negative"}
      />
            <MyButton
        text={"버튼"}
        onClick={() => alert("버튼 클릭")}
        type={"default"}
      />
    </div>
  );
}

 

 

 

 

728x90