headless component

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

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

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일간 못갔습니다..

0개의 댓글

관련 채용 정보