미새문지

24.08.21 day50 공용 컴포넌트 작성 방식 본문

개발 TIL

24.08.21 day50 공용 컴포넌트 작성 방식

문미새 2024. 8. 21. 23:45
728x90

코드를 짜다보면 같은 UI를 가진 컴포넌트를 만들 때가 정말 많은 것 같다.  UI가 같지만 쓰는 페이지도 다르고 해서 처음에는 각 코드에 같은 css와 태그를 쑤셔넣었지만, 컴포넌트를 나누는 걸 익숙하게 느낄 때쯤 같은 코드를 반복하는게 뭔가 효율이 안 좋은 것 같아 공용 컴포넌트를 연습하게 되었다.

 

주로 UI가 겹치는 부분은 어느 페이지든 보이는 header와 footer, 그리고 로그인이나 회원가입같은 정보를 작성하는 input 태그, 해당 사이트의 컨셉을 가진 색상 div 등이 있는 것 같다.

input 태그를 예시로 들어보자

import styled from "styled-components";

interface CommonInputProps {
  typeValue: string;
  placeholderValue: string;
}

const CommonInput: React.FC<CommonInputProps> = ({
  typeValue,
  placeholderValue,
}) => {
  return (
    <>
      <Input type={typeValue} placeholder={placeholderValue} />
    </>
  );
};
export default CommonInput;

const Input = styled.input`
  width: 90%;
  border: 3px solid rgba(255, 164, 228, 0.5);
  border-radius: 13px;
  padding: 10px 10px;
  margin-bottom: 10px;
  font-size: 14px;
  outline: none;
`;

위 코드는 input 태그 하나를 가진 컴포넌트이다. 같은 UI를 사용하기 위해 하나의 컴포넌트로 분리했지만, 입력받을 데이터 값은 다를 수 있다. 이 때 입력이나 설정이 다를 경우 props를 사용해 부모 컴포넌트에서 해당 설정이나 데이터를 입력받을 준비를 하면 된다.

위 코드는 input의 type과 placeholder를 props로 입력받아 값을 적용하고 있다.

props를 전달해줄 부모 컴포넌트에서는 자식 컴포넌트에서 지정한 props 명에 들어갈 값을 넣어주면 된다.

그리고 해당 input값에 입력될 값을 저장해줘야 하는데 이건 onChange로 입력될 값을 감지해서 useState를 사용해 값을 담아주면 된다.

import styled from "styled-components";
import BackHeader from "../common/backHeader";
import CommonInput from "../common/commonInput";
import NextBtn from "./nextBtn";
import SignupCount from "./signupCount";
import SignupGuide from "./signupGuide";
import PwVisible from "../common/pwVisible";
import React, { useState } from "react";

const Signup1: React.FC = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [passwordConfirm, setPasswordConfirm] = useState("");

  return (
    <>
      <Signup1Wrapper>
        <BackHeader />
        <SignupBox>
          <SignupCount count="1" />
          <SignupGuide text="이메일과 비밀번호를 입력해주세요." />
          <EmailBox>
            <CommonInput
              typeValue="email"
              placeholderValue="이메일"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
            <EmailCheck>√ 8자리 이상</EmailCheck>
            <EmailCheck>
              √ 대문자, 소문자, 숫자, 특수문자 중 2개 이상
            </EmailCheck>
          </EmailBox>
          <CommonInput
            typeValue="password"
            placeholderValue="비밀번호"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
          <PwVisible />
          <CommonInput
            typeValue="password"
            placeholderValue="비밀번호 확인"
            value={passwordConfirm}
            onChange={(e) => setPasswordConfirm(e.target.value)}
          />
          <NextBtn />
        </SignupBox>
      </Signup1Wrapper>
    </>
  );
};
export default Signup1;

const Signup1Wrapper = styled.div`
  width: 100%;
  display: flex;
  flex-direction: column;
`;

const SignupBox = styled.div`
  margin: 50px auto;
`;

const EmailBox = styled.div`
  display: flex;
  flex-direction: column;
  margin: 10px 0;
`;

const EmailCheck = styled.div`
  font-size: 11px;
  margin-left: 10px;
  color: #c9c9c9;
`;

그리고 해당 값을 저장하기 위해 자식 컴포넌트에서는 해당 값을 어디에서 입력되는지 지정해주면 된다.

import styled from "styled-components";

interface CommonInputProps {
  typeValue: string;
  placeholderValue: string;
  value: string;
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const CommonInput: React.FC<CommonInputProps> = ({
  typeValue,
  placeholderValue,
  value,
  onChange,
}) => {
  return (
    <>
      <Input
        type={typeValue}
        placeholder={placeholderValue}
        value={value}
        onChange={onChange}
      />
    </>
  );
};
export default CommonInput;

const Input = styled.input`
  width: 90%;
  border: 3px solid rgba(255, 164, 228, 0.5);
  border-radius: 13px;
  padding: 10px 10px;
  margin-bottom: 10px;
  font-size: 14px;
  outline: none;
`;

해당 input값의 type, placeholder는 입력창이 뭘 받을지와 입력 예시 등의 설정을 지정해주는 거고 value는 해당 입력창에 무슨 값이 입력되있는지, onChange는 입력창의 값이 바뀌면 해당 변화를 감지해주는 역할을 한다.

입력값이 string이 아니라 정수값 등의 다른 타입이 들어갈 수도 있는데 이 경우에는 interface의 타입 지정 부분에 number값을 추가해주면 된다.

interface CommonInputProps {
  typeValue: string;
  placeholderValue: string;
  value: string | Number;
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

 

공용 컴포넌트를 연습하게 된 계기는, 중복된 태그를 여러 곳에서 사용하다 보니, 수정할 때마다 모든 부분을 일일이 바꿔줘야 하는 불편함을 느꼈기 때문이다.

반면, 공용 컴포넌트를 사용하면 한 번의 수정으로 모든 곳에 변경사항이 반영되어 코드 양이 줄고, 효율성도 높아진다.

아직 세세하게 합치기에는 실력이 부족하지만 연습하다보면 또 불편한 점을 찾아 발전하면 될 것 같다.

728x90

'개발 TIL' 카테고리의 다른 글

24.08.23 day52 캡슐화, 미들웨어  (0) 2024.08.23
24.08.22 day51 작업 일지  (0) 2024.08.22
24.08.20 day49 로그인 UI  (0) 2024.08.20
24.08.19 day48 HTML 작성 규칙  (0) 2024.08.19
24.08.16 day47 필터 구현  (0) 2024.08.16