본문 바로가기
개발 일지/TIL

[ React ] 하나의 modal로 버튼에 따라 다른 내용 출력하기

by CODESIGN 2023. 1. 24.

modal 창 하나로 수정 버튼에 따라 그에 맞는 내용이 modal 창에 뜨게끔 구현을 해보았다.

 

 

 

 

 

 

 

 

 

 

MyPage.jsx - 수정 버튼 


import EditModal from '../../components/MyPage/EditModal/EditModal';
import { Fragment, useEffect } from 'react';
import {
  MyPageContainer,
  MyInfoContainer,
  MyPageTagTitle,
  MyInfoInput,
  MyInfoEditButton,
  NickNameContainer,
  GithubContainer,
  MyPageTabsContainer,
  InputCheckContainer,
} from './style.js';

const MyPage = () => {
  const [github, setGithub] = useState('https://github.com/');
  const [userName, setUserName] = useState('눈누난나');
  
  // True: 닉네임 수정, False: Github 수정
  const [contentInfo, setContentInfo] = useState('');

  // 모달창 노출 여부 state
  const [modalOpen, setModalOpen] = useState(false);

  
  // 닉네임 수정 모달 창 열림
  const openUserNameModal = () => {
    setModalOpen(true);
    setContentInfo(true);
  };

  // 깃허브 수정 모달 창 열림
  const openGithubModal = () => {
    setModalOpen(true);
    setContentInfo(false);
 };

  // 닉네임 입력
  const InputUserName = (e) => {
    setUserName(e.target.value);
  };

  // 깃허브 링크 입력
  const InputGithub = (e) => {
    setGithub(e.target.value);
  };

  return (
    <Fragment>
      <MyPageContainer>
        {/* 닉네임, 깃허브 링크 수정 */}
        <MyInfoContainer>
          <NickNameContainer>
            <MyPageTagTitle>닉네임</MyPageTagTitle>
            <InputCheckContainer>
              <MyInfoInput>{userName}</MyInfoInput>
              <MyInfoEditButton onClick={openUserNameModal}>
                수정
              </MyInfoEditButton>
              {modalOpen && (
                <EditModal
                  setModalOpen={setModalOpen}
                  setContentInfo={contentInfo}
                  setUserName={userName}
                />
              )}
            </InputCheckContainer>
          </NickNameContainer>
          <GithubContainer>
            <MyPageTagTitle>GitHub</MyPageTagTitle>
            <InputCheckContainer>
              <MyInfoInput>{github}</MyInfoInput>
              <MyInfoEditButton onClick={openGithubModal}>
                수정
              </MyInfoEditButton>
              {modalOpen && (
                <EditModal
                  setModalOpen={setModalOpen}
                  setContentInfo={contentInfo}
                  setUserName={userName}
                  setGithub={github}
                />
              )}
            </InputCheckContainer>
          </GithubContainer>
        </MyInfoContainer>
      </MyPageContainer>
    </Fragment>
  );
};

export default MyPage;

 

style.js


import styled from 'styled-components';
import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';

export const MyPageContainer = styled.div`
  display: flex;
  margin: 0 auto;
  max-width: 90%;

  @media screen and (max-width: 800px) {
    flex-direction: column;
    margin: 0 auto;
  }
`;

export const MyInfoContainer = styled.div`
  padding-top: 65px;
  flex: 30%;
  margin: 0 auto;

  @media screen and (max-width: 800px) {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
`;

export const NickNameContainer = styled.div`
  margin-bottom: 40px;

  @media screen and (max-width: 800px) {
    width: 430px;
  }
`;

export const InputCheckContainer = styled.div`
  display: flex;
  justify-content: space-between;
`;

export const GithubContainer = styled.div``;

export const MyPageTagTitle = styled.div`
  font-weight: 600;
`;

export const MyInfoInput = styled.p`
  border: none;
  border-bottom: 0.6px solid #c6c6c6;
  min-width: 200px;
  width: 70%;
  margin: 20px 10px 20px 0;
  outline: none;
  flex: 80%;
`;

export const MyInfoEditButton = styled.button`
  border: 1px solid #205295;
  border-radius: 7px;
  color: #205295;
  background-color: #fff;
  font-weight: 600;
  padding: 5px 10px;
  margin-right: 20px;
  height: 35px;
  width: 50px;
  cursor: pointer;
  flex: 20%;

  &:hover {
    background: #205295;
    color: #fff;
  }

  @media screen and (max-width: 800px) {
    margin-right: 0px;
  }
`;

 

 

닉네임 수정 버튼을 누를 시 아래와 같은 모달 창이 뜬다.

 

 

깃허브 수정 버튼을 누를 시 아래와 같은 모달 창이 뜬다.

 

 

Modal.jsx - 모달 창


import React, { useState } from 'react';
import {
  ModalBackground,
  ModalContainer,
  ModalTopItems,
  ModalClose,
  MyInfoInput,
  ButtonContainer,
  CancelButton,
  SaveButton,
} from './style.js';

const EditModal = ({
  setModalOpen,
  setContentInfo,
  setUserName,
  setGithub,
}) => {
  const [currentInput, setCurrentInput] = useState();

  // X버튼 onClick 이벤트 핸들러
  const closeModal = () => {
    setModalOpen(false);
  };

  // 닉네임 입력
  const getInput = (e) => {
    setCurrentInput(e.target.value);
  };

  // 수정 취소
  const cancelEdit = () => {
    setModalOpen(false);
  };

  // 수정 저장
  const saveEdit = () => {
    setModalOpen(false);
  };

  return (
    <ModalBackground>
      <ModalContainer>
        <ModalTopItems>
          {setContentInfo ? <h3>닉네임 변경</h3> : <h3>Github Link 변경</h3>}

          <ModalClose onClick={() => closeModal()}>X</ModalClose>
        </ModalTopItems>

        <MyInfoInput
          onChange={getInput}
          value={currentInput}
          maxLength={10}
          placeholder={setContentInfo ? setUserName : setGithub}
        />
        <ButtonContainer>
          <CancelButton onClick={() => cancelEdit()}>취소</CancelButton>
          <SaveButton onClick={() => saveEdit()}>저장</SaveButton>
        </ButtonContainer>
      </ModalContainer>
    </ModalBackground>
  );
};

export default EditModal;

 

 

style.js


import styled from 'styled-components';

export const ModalBackground = styled.div`
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(67, 79, 101, 0.8);
`;

export const ModalContainer = styled.div`
  /* 모달창 크기 */
  width: 420px;
  height: 220px;

  /* 최상단 위치 */
  z-index: 999;

  /* 모달 배치 */
  /* translate는 본인의 크기 기준으로 작동한다. */
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);

  /* 모달창 디자인 */
  background-color: #fff;
  border-radius: 7px;
  padding: 15px 35px 10px 35px;
  box-sizing: border-box;
`;

export const ModalTopItems = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
`;

export const ModalClose = styled.button`
  height: 20px;
  border: none;
  background-color: transparent;
  font-weight: 600;
  cursor: pointer;
  color: #d7d7d7;
  font-size: 16px;
  :hover {
    color: #000;
  }
`;

export const MyInfoInput = styled.input`
  border: none;
  border-bottom: 0.6px solid #c6c6c6;
  min-width: 200px;
  width: 100%;
  margin: 20px 10px 20px 0;
  outline: none;
  flex: 80%;
`;

export const ButtonContainer = styled.div`
  padding-top: 20px;
  display: flex;
  gap: 10px;
  justify-content: right;
`;

export const CancelButton = styled.button`
  background-color: rgba(233, 236, 242, 0.8);
  border: none;
  box-sizing: border-box;
  padding: 8px 15px;
  border-radius: 7px;
  font-weight: 600;
  cursor: pointer;

  :hover {
    background-color: rgba(188, 188, 188, 0.4);
  }
`;

export const SaveButton = styled(CancelButton)`
  background-color: rgba(36, 55, 99, 0.8);
  color: #fff;

  :hover {
    background-color: rgba(36, 55, 99);
  }
`;

 

 

댓글