React Platform Design

homewiz·2024년 12월 19일

React & typescript

목록 보기
17/18

중복 코드는 죽어도 쓰기 싫다.

모바일과 pc 화면 구성을 따로 해줘야 하는 경우 핵심 코어 부분은 공유 할수 있도록 개발 하기 위한 방법을 연구하다가
결국 아래 2가지 방안이 최종 결론으로 남았다.

  1. inner meta component code
  2. outer meta compoennt code

1번의 장점은 state, function을 바로 사용 할수 있는 간결함이다.
2번의 장점은 복잡도가 약간 올라가는 대신 안정성이 좋다.

import React, { useMemo, useState } from "react";

const TestPage1 = ({isMobile = false}: {isMobile: boolean}) => {
  const [name, _name] = useState("123");
  const [age, _age] = useState(0);
	
  // useMemo에서 state값을 바로 쓰면 안되고 파라미터로 받아서 써야만한다. 
  // state를 바로 쓰고 싶다면 해당 함수를 useCallback으로 감싸줘야 한다. 
  function getMerge(name, age){
    return name + ":" + age;
  }
  
  const Mobile = useMemo(() => {
    return (
      <div>
        <div>this is Mobile</div>
        <div>{age}</div>
        <input onChange={evt => _age(Number(evt.target.value))} />
        <div>{name}</div>
        </* 해당 함수는 useCallback이 아니므로 내부에 name,age를 바로 사용불가, 파라미터로 전달 해줘야 한다. */>
        <div>{getMerge(name, age)}</div> 
        <input onChange={evt => _name(evt.target.value)} />
      </div>
    );
  }, [age, name]); // 감시 대상 기재를 실수 할수 있다.

  const Pc = useMemo(() => {
    return (
      <div>
        <div>this is Pc</div>
        <div>
          Name: {name}
          <input onChange={evt => _name(evt.target.value)} />
        </div>
        <div>
          Age: {age}
          <input onChange={evt => _age(Number(evt.target.value))} />
        </div>
        <div>{getMerge(name, age)}</div>
      </div>
    );
  }, [name, age]);

  return !isMobile ? Pc : Mobile;
};

export default TestPage1;
import React, { useState } from "react";

// interface 를 한번더 정의 해줘야 한다.
interface IPlatformAtts {
  name: string;
  setName: (value: string) => void;
  age: number;
  setAge: (value: number) => void;
}

const TestPage2 = ({isMobile = false}: {isMobile: boolean}) => {
  const [name, setName] = useState("123");
  const [age, setAge] = useState(0);

  // TestPage1과 달리 state값을 쓰면된다.
  function getMerge(){
    return name + ":" + age;
  }
  
  const props = { name, setName, age, setAge };
  return (
    <div>
      {isMobile ? <Mobile {...props} /> : <Pc {...props} />}
    </div>
  );
};

// 사용할 변수, 함수를 다시 선언 해야 한다.
const Mobile = React.memo(({ name, setName, age, setAge,getMerge }: IPlatformAtts) => (
  <div>
    <h2>This is Mobile</h2>
    <div>
      <label>Age: </label>
      <input type="number" value={age} onChange={e => setAge(Number(e.target.value))} />
    </div>
    <div>
      <label>Name: </label>
      <input value={name} onChange={e => setName(e.target.value)} />
    </div>
    <div>{getMerge()}</div>
  </div>
));
Mobile.displayName = "Lsports"; // 리액트 코딩룰에는 이름을 기재 하여야만한다.

// 사용할 변수, 함수를 다시 선언 해야 한다.
const Pc = React.memo(({ name, setName, age, setAge,getMerge }: IPlatformAtts) => (
  <div>
    <h2>This is PC</h2>
    <div>
      <label>Age: </label>
      <input type="number" value={age} onChange={e => setAge(Number(e.target.value))} />
    </div>
    <div>
      <label>Name: </label>
      <input value={name} onChange={e => setName(e.target.value)} />
    </div>
    <div>{getMerge()}</div>
  </div>
));
Pc.displayName = "Lsports";// 리액트 코딩룰에는 이름을 기재 하여야만한다.

export default TestPage2;

개인 결론 및 추천
TestPage2
둘다 상황에 맞게 사용한다.(대부분 TestPage1을 사용 하지 않을까 싶다)
소스 구성을 크게 page, component 2가지로 봤을때
페이지쪽은 TestPage1, 컴포넌트쪽에서 재사용이 있는 경우 TestPage2 아니면 TestPage1을 선택한다.

주의점 TestPage1은 useMemo선언 할때 감시 대상변수를 반드시 기재 해줘야 변화에 따른 랜더링이 원활하게 이루어 진다.


GPT 비교 요약

특성TestPage1TestPage2
간결성간단한 구조로 빠르게 구현 가능컴포넌트 분리로 구조가 다소 복잡
재사용성Mobile, PC 뷰의 재사용 어려움Mobile, PC 뷰 재사용 및 독립 테스트 가능
의존성 관리useMemo의 의존성 배열 관리 필요의존성 배열 관리 필요 없음
렌더링 최적화일부 최적화(useMemo) 제공React.memo를 통한 불필요한 렌더링 방지 가능
유지보수중복 코드로 수정 시 각 뷰를 반복적으로 변경해야 함컴포넌트 단위로 관리되어 수정이 용이
적합한 프로젝트소규모 프로젝트, 간단한 UI중/대규모 프로젝트, 재사용성 고려 시

GPT 결론 및 추천
TestPage1:

소규모 프로젝트, 간단한 UI, 빠른 개발이 필요한 경우 적합.
유지보수 및 재사용성이 덜 중요할 때 사용.

TestPage2:

중/대규모 프로젝트, 컴포넌트의 재사용성과 독립성이 중요한 경우 적합.
유지보수 용이성, 가독성, 확장성을 고려해야 하는 경우 추천.

GPT 권장 선택: 프로젝트 규모와 요구사항에 따라 다르지만, 일반적으로 확장성과 유지보수성을 고려한다면 TestPage2가 더 적합합니다.

본인 권장 선택: 페이지쪽은 TestPage1, 컴포넌트쪽에서 재사용이 있는 경우 TestPage2 아니면 TestPage1을 선택한다.

0개의 댓글