[React 완벽 가이드] Section 4: 리액트 심화

gonn-i·2024년 5월 28일
0

React 완벽 가이드

목록 보기
2/18
post-thumbnail

본 포스트는 Udemy 리액트 완벽가이드 2024 를 듣고 정리한 내용입니다.

목차 🌳
1️⃣ 비JSX 구조
2️⃣ Component 분할 및 타입 동적 할당
3️⃣ Propxy props와 기본값 설정

📁 JSX

JSX는 브라우저에서 지원되지 않기 때문에, 추가적으로 빌드 과정을 통해 변환 절차를 거쳐 우리의 화면에 보여지게 된다.

그렇다면? JSX 없이도 UI를 그릴 수 없을까? 🧐

근데 JSX 없이 UI를 만들 수 있을까? -> 네!

있다! 그치만 조금 코드라인이 더 필요할뿐!
jsx를 이용한 코드

<div id="content">
	<p>Hello World!</p<
</div>

jsx를 이용하지 않은 코드

React.createElement(
	'div',
  	{ id: 'content'},
  	React.createElement(
    'p',
     null,
     'Hello World'
    )
);

하지만, 대부분 JSX를 사용하니 그냥 참고할것

JSX는 하나의 요소 감싸져서 반환 필수!

📍 JSX 사용하는 규칙
1️⃣ 무조건 하나의 부모 요소로 감싸서 반환 (return)
-> 여러 형제 요소(n개의 값)를 한번에 꺼낼 수 없기 때문

[P] 근데, <div> ... </div> 로 다시 감싸면 DOM에 중복되는 요소되는 문제가 발생하는데

이때는,
-> ⭐️ [Sol] Fragment Component <Fragment></Fragment>를 사용하거나
-> ⭐️ [Sol] 빈태그 <></> 를 사용하면 된다.

이로써, div를 대체하지만, DOM에 불필요한 div 를 만들지 않을 수 있음!


📁 Components

State (상태) 및 feature (기능) 별로 컴포넌트를 잘게 구성하기 🧩 !!

component를 하나로만 크게 구성하다보면,
TabBtn(일부 Section)을 누를때 ➡️ 부모 컴포넌트에 선언되었던 상태값이 변경되고, 해당 페이지가 전체 re-rendering 되는 문제가 있다.
(부모 컴포넌트 -> 자식 컴포넌트까지 모두 재실행되기 때문)

이때, 불필요한 재실행을 막는게 프로젝트 관리에 있어서 중요하다!
(어떤 시점에 재랜더링(이 이뤄지고, 어디까지 재랜더가 되는지를 잘 파악하는게 프론트의 임무 아닐까? 🤓 )

따라서, 최상위 컴포넌트에서 일부분(하나의 Section)만을 위한 재랜더링을 피해 컴포넌트를 잘게 쪼개는게 좋다 이말이다!

(왜냐, 최상위 컴포넌트에서 상태변화가 나타나면, 그 자식에 .. 자식에.. 자식까지... 가기 때문에)

App.jsx

import Header from './components/Header/Header.jsx';

import CoreConcepts from './components/CoreConcepts.jsx';
import Examples from './components/Examples.jsx';

function App() {
  return (
    <div>
      <Header />
      <CoreConcepts />
      <main>
        <Examples />
      </main>
    </div>
  );
}

export default App;

동적으로 Component 타입 할당해주기

재사용성을 장점으로 가진 react Component 를 구성하기 위해서는, html태그 타입을 동적으로 넘겨주는 것이 매우 중요하다.
(규모가 큰 프로젝트일수록 더더욱! ) .. 생각해보아라, menu로 감싼 component따로, ul로 감싼 component따로 모든 것을 만드는 것은 비효율적이겠는가!
리액트로는 최대한 reusable 한 컴포넌트를 만들기 위해서 고민하는게 좋겠다!!

타입을 할당해줄때도, prop을 이용해서 넘겨주면 되겠다!
즉, 컴포넌트의 식별자를 ➡️ 속성값 (프롭)으로 보내준다는 것이다 ⭐️

Examples.jsx

<Tab ButtonsContainer="menu" buttons={ <> ... </> }>
  {tabContent}
</Tab>

Tab.jsx

export default function Tab({ children, buttons, ButtonsContainer }) {
  return (
    <>
      <ButtonsContainer>{buttons}</ButtonsContainer>
      {children}
    </>
  );
}

단 주의할 점 2가지 📍
1️⃣ 받는 쪽의 컴포넌트에서 넘겨받는 속성값이, custom component로서 사용 가능해야 함
-> 반드시 대문자로 시작하거나
(처음부터 prop 을 대문자로 시작하게 만들거나)
-> 상수나 변수로 재설정된 속성인 경우, 대문자로 시작
(소문자로 된 prop을 받아서 대문자로 시작하는 변수나 상수에 담아주기)
2️⃣ 식별자에서는 문자열 이름을 사용하는데, html 태그를 입력해줘야 인식할 수 있음 (ex. menu ul div)

근데 나 항상 컴포넌트 타입을 동적으로 새로 주는게 아니라, n번 menu로 주고 1번 다른걸로 주고 싶은데? 🤨

⬇️

그렇다면 props에 기본값 설정하기!

기본값 사용하는 경우

export default function Tab({ children, buttons, ButtonsContainer = 'menu' }) {
  return (
    <>
      <ButtonsContainer>{buttons}</ButtonsContainer>
      {children}
    </>
  );
}

이렇게 설정해주면, Tab Component를 사용하는 쪽에서, menu를 사용하는 경우에 굳이 ButtonsContainer의 value를 설정해주지 않아도 기본값을 채택하게 된다!

만일, div 태그를 사용하고 싶다면 본디 props를 사용한 것처럼 값을 할당해주면 된다!

기본값 사용하지 않는 경우

      <Tab ButtonsContainer="div" buttons={ <> ... </>} />

📁 Props

proxy props

proxy props란,
해당 컴포넌트에서 사용할 수 있는 모든 props를 모아 하나로 병합! 하여 하나의 props object (속성 객체)를 만들어주는 방법 👀

사용방법 📖
1️⃣ spread operator 를 이용해 인자에서 프롭을 받고,
-> ex) ...props(이름은 props 말고 다른 것으로 해도 됨) ,
2️⃣ prop를 사용하듯이 사용해주면 된다.
-> ex) {...props}

🤨 왜 굳이 사용해야 하나?

1️⃣ 중간 컴포넌트에서 ➡️ 하위 컴포넌트로 props를 전달할때에, 많은 props를 수동으로 나열하고 전달해야 할 경우
-> 코드 중복, 비효율 발생
2️⃣ props를 추가하거나, 기존의 props 변경시 하위컴포넌트까지 바꿔줘야하는 경우,
-> 번거로움 + 유지보수 bad
3️⃣ 중간 컴포넌트가 여러개 있을 경우
-> 각 컴포넌트마다 props를 명시적으로 보여주면 코드를 읽기 힘들고 데이터의 흐름을 추적하기 어려움

0개의 댓글