컴포넌트 재사용하기

김찬영·2021년 1월 3일
0

Mini Project

목록 보기
3/4


---Modal.js---

import React, {Component} from 'react';
import Form from './Components/Form';
import './Modal.scss';

export default class Modal extends Component {
  state = {
    clickedType: '',
  };

  handleClickedType = (e) => {
    this.setState({
      clickedType: e.target.innerText,
    });
  };
  render() {
    return (
      <div className="Modal">
        {/* <Form format={signUpProps} /> */}
        <Form
          handleClickedType={this.handleClickedType}
          format={
            this.state.clickedType === '로그인' ? signInProps : signUpProps
          }
        />
      </div>
    );
  }
}

const signUpProps = {
  type: 'signUp',
  text: '회원가입',
  data: [
    {
      type: 'name',
      text: '이름',
    },
    {
      type: 'email',
      text: '이메일',
    },
    {
      type: 'password',
      text: '비밀번호',
    },
  ],
};

const signInProps = {
  type: 'signIn',
  text: '로그인',
  data: [
    {
      type: 'email',
      text: '이메일',
    },
    {
      type: 'password',
      text: '비밀번호',
    },
  ],
};

최상위 부모 Modal 컴포넌트에서 clickedType state을 설정한다. 그리고 자식컴포넌트 Form에서 클릭할때마다 e.target.innerText를 clikedType state에 저장한다. 이와 동시에 format 속성에서 clikedType이 로그인일때는 signInProps 객체를 보내고 회원가입 일떄는 signUpProps 객체를 보낸다. 이 객체들은 로그인 , 회원가입에 대한 각각의 데이터들이다.


---Form.js----

export default class Form extends Component {
  render() {
    const {format, handleClickedType} = this.props;

    return (
      <FormLayout>
        <h2>{format.text}</h2>
        <div>
          {format.data.map((input, idx) => (
            <Input key={idx} type={input.type} text={input.text} />
          ))}
        </div>
        <Button value={format.text} />

        <p className="isAlreadyLogin">
          {format.type === 'signUp'
            ? '이미 가입하셨나요?'
            : '계정이 없으신가요'}
          <span onClick={(e) => handleClickedType(e)}>
            {format.type === 'signUp' ? '로그인' : '회원가입'}
          </span>
        </p>
      </FormLayout>
    );
  }
}


부모에서 받은 format props를 사용한다. <h2>에서는 signUpProps와 signInProps의 객체안의 text를 사용한다. <Input>컴포넌트에서 각 객체안에 있는 data를 맵핑하여 <Input>컴포넌트에서 사용하기 위해서 type, text를 props로 전달한다. Button도 똑같이 설정한다. 이렇게하면 버튼을 클릭할때마다 format의 데이터가 변경되므로 format의 벨류 값들도 변하게 된다.

만약 type이 siginUp이면 "이미 가입하셨나요?" signUp 아니라면 "계정이 없으신가요"를 설정한다. 즉, type이 회원가입이면 "이미 가입하셨나요?"문구를 띄우고, 로그인 type에서는 "계정이 없으신가요?"를 표시한다.

부모에게 handleClickedType props를 받아 onclick을 사용하여 event 인자를 부모로 넘겨준다. 즉 자식컴포넌트에서 버튼을 클릭하면 이벤트가 부모 handleClickType 함수 인자로 넘겨진다. e.target.innerText는 즉 자식의 span안에 내용이 부모 state에 저장되어 format에서 조건문으로 사용하고있다.

import React, { Component } from "react";
import "./Input.scss";

export default class Input extends Component {
  render() {
    const { type, text } = this.props;

    return (
      <div className="Input">
        <div className="inputWrapper">
          <input type={type} placeholder={text} />
        </div>
      </div>
    );
  }
}

Input 컴포넌트에서도 type props를 전달받는다.clickedType이 signInProps이면 signInProps의data type이므로 "name", "email" , "password"를 받으므로 input이 3개가 생긴다.

profile
Front-end Developer

0개의 댓글