headless component

ijimlnosk·2024년 3월 15일
0
post-thumbnail
post-custom-banner

---- 과제 두번째 ----

2주차 과제를 하면서 이해가 잘되지 않은 부분이 꽤 있었다
그 중 headless component에 대해 알아보고자한다.

headless component란?

간단하게 말하자면 스타일이 되어있지 않은 컴포넌트다.

기능 변경이 많은 곳에서 유용하다고 한다.

아래는 과제를 진행하면서 사용한 간단한 headless component이다.

-headless select-
export const HeadlessSelect = ({ children, options, defaultSelected }) => {
    const [selected, setSelected] = useState(defaultSelected);

    const select = (value) => setSelected(value);

    return children({ selected, options, select });
};

-사용-
<HeadlessSelect defaultSelected={"1"} options={dropDownOption}>
                {({ options, select }) => (
                    <select>
                        {options?.map((option, index) => (
                            <option
                                key={index}
                                onClick={() => select(option.value)}
                            >
                                {option.label}
                            </option>
                        ))}
                    </select>
                )}
            </HeadlessSelect>

간단하게 select를 만들어 보았다.
select의 option을 여러개 넣어주기 위해서는 option을 배열로 생성하여 HeadlessSelect에 options라는 props로 넣어주었다.
이 options를 map으로 주어 여러개의 option을 생성할수있다.

커스텀 훅을 지원하는 방법으로도 headless component를 구현하는 경우가 있다고 나와있어서
과제 예시에 있는 modal을 만들어 보았다.

먼저 cutom hook으로 useModal을 생성해주었다.

import { useState } from "react";

const useModal = () => {
    const [isOpen, setIsOpen] = useState(false);

    const openModal = () => setIsOpen(true);
    const closeModal = () => setIsOpen(false);

    return { isOpen, openModal, closeModal };
};
export default useModal;

modal을 여닫는 기능을 해주는 custom hook이다.

다음으로 headless modal component를 만들었다.

import styled from "styled-components";

const HeadlessModal = ({ isOpen, children, closeModal }) => {
    if (!isOpen) return null;

    return (
        <ModalBackground onClick={closeModal}>
        // 이벤트를 부모요소나 다른요소로 넘어가지않게 하기위함 e.stopPropagation
            <ModalContent onClick={(e) => e.stopPropagation()}>
                {children}
                <button onClick={closeModal}>X</button>
            </ModalContent>
        </ModalBackground>
    );
};
export default HeadlessModal;

const ModalBackground = styled.div`
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
`;

const ModalContent = styled.div`
    background-color: #fff;
    padding: 20px;
`;

Global style을 사용하여 초기값을 설정해 줄 수있지만 우선 직접 선언해주었다.
사실 아직도 이렇게 쓰는게 맞는지 애매하다

사용

 <StyledButton
                text={"open modal"}
                theme={"neonOrangeYellow"}
                size={"medium"}
                onClick={openModal}
            />
            <HeadlessModal isOpen={isOpen} closeModal={closeModal}>
                <h2>title</h2>
                <p>open modal</p>
            </HeadlessModal>

과제를 진행하면서 만든 공용컴포넌트인 버튼으로 버튼을 만들어 주었다.
버튼 클릭 시 modal이 나오고 x, 혹의 modal의 바깥을 누르면 modal이 닫히는 구조이다.

다른 부분들도 연습을하고...스타일을 따로 주지않아서 구조가 조금 형편없...다..
시간이 되면 디자인을 이쁘게 꾸며줄 예정이다...

TMI) 운동을 4일간 못갔습니다..

post-custom-banner

0개의 댓글