2024.03.04(월)

🤥모킹 서버 작성

  • Mock Service Worker (MSW)
    • 존재하지 않는 API에 대한 응답을 mocking
    • service worker에서 요청 처리
    • chrome 기준 devTool의 Application / Service workers의 “Bypass for network”로 일시 정지
  • Moking Server로 책 리뷰 응답 만들기
    • MSW 설치 & 설정
      • npm i msw --save-dev
      • npx msw init public/ --savepublic 폴더에 mockServiceWorker.js 파일이 생성됨
      • index.tsx에 개발 모드일 때만 mock server를 실행시키는 코드 추가
        if (process.env.NODE_ENV === "development") {
          const { worker } = require("./mock/browser");
          worker.start();
        }
    • service worker API 사용
  • 🤥fakerjs로 dummy data 만들기
    • import { fakerKO as faker } from '@faker-js/faker';로 사용하면 한국어 data를 만들 수 있음!

관련 커밋 바로가기

📋리뷰 목록

관련 커밋 바로가기

✍️리뷰 작성

관련 커밋 바로가기

🔽드롭다운

관련 커밋 바로가기

🎨CSS Position

  • position: static; (default)

    • 요소는 일반적인 문서 흐름에 따라 배치됨
    • 이동 불가
  • position: relative;

    • 요소는 일반적인 문서 흐름에 따라 배치됨
    • 자기 자신을 기준으로 top, right, bottom, left offset 적용
  • position: absolute;

    • 요소는 일반적인 문서 흐름에서 제거됨

    • page layout에 요소의 공간 ❌

    • 가장 가까운 positioned ancestor을 기준으로 top, right, bottom, left offset 적용
      (positioned ancestor가 없으면 초기 containing block 기준)

    • 일반적으로 기준이 될 부모에게 position: relative; 를 부여하고 원하는 위치를 지정

      • offset은 왼쪽 위 모서리 기준이기 때문에 부모 요소의 가운데에 자식 요소를 배치하고 싶을 경우 다음과 같은 패턴을 많이 사용

        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
  • position: fixed;

    • 요소는 일반적인 문서 흐름에서 제거됨
    • page layout에 요소의 공간 ❌
    • viewport(window)를 기준으로 배치 (즉, 페이지에 위치가 고정됨)
  • position: sticky;

    • 요소는 일반적인 문서 흐름에 따라 배치됨
    • 가장 가까운 scrolling ancestor를 기준으로 top, right, bottom, left offset 적용

🪝useRef Hook

Rendering에 필요하지 않은 값을 참조할 수 있는 React Hook

import { useRef } from 'react';

const ref = useRef(initialValue)
  • useRef는 처음에 제공한 initialValue로 설정된 단일 current 프로퍼티가 있는 ref 객체를 반환
    { 
      current: initialValue
    }
  • React는 initial ref value를 한 번 저장하고, 다음 rendering부터는 이를 무시

💡 state와 비슷하다고 생각할 수 있지만 useRef는 ref를 변경해도 re-render를 trigger ❌

  • ref는 component의 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 적합 (component에 일부 값을 저장해야 하지만 rendering logic에는 영향을 미치지 않는 경우) 🔗
    • ref의 가장 일반적인 사용 사례는 DOM 요소에 액세스하는 것!
  • ref 정보는 각각의 component에 local로 저장됨
  • set 함수를 이용해 state 변수를 업데이트해야하는 state와 달리 ref일반 JavaScript 객체이기 때문에 읽기, 쓰기 모두 가능
    • ref.current로 값을 읽기 (rendering 중에는 값을 읽을 수 없음) 🔗
    • ref 내부의 값을 업데이트하려면 current 프로퍼티를 수동으로 변경 → ref.current = newValue;
  • ref vs state
refstate
useRef(initialValue) returns { current: initialValue }useState(initialValue) returns the current value of a state variable and a state setter function ([value, setValue])
Doesn’t trigger re-render when you change it.Triggers re-render when you change it.
Mutable—you can modify and update current’s value outside of the rendering process.“Immutable”—you must use the state setting function to modify state variables to queue a re-render.
You shouldn’t read (or write) the current value during rendering.You can read state at any time. However, each render has its own snapshot of state which does not change.
  • Node에 대한 ref 가져오기
    • useRef로 생성한 ref 객체를 조작하려는 DOM 노드의 JSX에 **ref 속성**으로 전달

      const inputRef = useRef(null);
      return <input ref={inputRef} />;
    • React가 DOM 노드를 생성하고 화면에 그린 후, React는 ref 객체의 current 프로퍼티를 DOM 노드로 설정!

    • 노드가 화면에서 제거되면 React는 current 프로퍼티를 다시 null로 설정

      ⚠️ ref 속성은 <input />과 같은 browser element를 출력하는 built-in component에서만 사용 가능!
      Custom component에 ref를 넣으면 기본적으로 null이 반환됨

      • 기본적으로 React는 컴포넌트가 다른 컴포넌트의 DOM 노드에 접근하는 것을 (심지어 자식에게도) 허용하지 ❌
      • 다른 component의 DOM 노드에 접근하려면 하려면 접근하려는 노드를 포함하고 있는 component를 [forwardRef](https://react-ko.dev/reference/react/forwardRef) API로 감싸야 함 🔗 🔗
  • 참고 자료

📑탭

관련 커밋 바로가기

🎞️React.Children.toArray()

props로 받은 children의 집합을 배열로 반환 → map으로 순회 가능

interface TabsProps {
    children: React.ReactNode;
}

function Tabs({ children }: TabsProps) {
    const [activeIndex, setActiveIndex] = useState(0);

    const tabs = React.Children.toArray(children) as React.ReactElement<TabProps>[];

    return (
        <TabsStyle>
            <div className="tab-header">
                {
                    tabs.map((tab, index) => (
                        <button onClick={() => setActiveIndex(index)} className={activeIndex === index ? "active" : ""}>
                            {tab.props.title}
                        </button>
                    ))
                }
            </div>
            <div className="tab-content">
                {
                    tabs[activeIndex]
                }
            </div>
        </TabsStyle>
    );
}
profile
이것저것 관심 많은 개발자👩‍💻

0개의 댓글