개발하는 너구리

TIL-24.05.08 본문

TIL

TIL-24.05.08

너구리개발자 2024. 5. 8. 23:57

 

SPA란?

  • Single Page Application
  • 리액트는 SPA의 형식입니다.
  • 페이지가 하나라는 뜻으로, 하나의 페이지 안에서 자바스크립트가 필요한 페이지나 정보만 동적으로 그려줍니다.
  • 장점
    • 새 페이지로 넘어갈 때마다 서버에서 HTML/CSS, JS 소스를 가져올 필요가 없어 새로고침이 필요하지 않아요.
    • 사용자에게 물흐르듯 끊김없는 웹 앱 경험을 선사해줄 수 있어요.
  • 단점
    • 처음에 필요한 리소스를 다 가져와야 해서 초기 구동 속도가 느립니다.

JSX

  • JavaScript를 확장한 문법
  • 브라우저에서 실행하기 전에 Babel을 사용하여 일반 자바스크립트 형태의 코드로 변환됩니다.
    • Babel 은 자바스크립트의 문법을 확장해주는 도구입니다. 아직 지원되지 않는 최신 문법이나, 편의상 사용하거나 실험적인 자바스크립트 문법들을 정식 자바스크립트 형태로 변환해줌으로서 구형 브라우저같은 환경에서도 제대로 실행 할 수 있게 해주는 역할을 합니다.
    • Babel은 JSX를 React.createElement() 호출로 컴파일합니다.
  • JSX도 표현식!
    • 컴파일이 끝나면, JSX 표현식이 정규 JavaScript 함수 호출이 되고 JavaScript 객체로 인식됩니다.
    • 즉, JSX를 if 구문 및 for loop 안에 사용하고, 변수에 할당하고, 인자로서 받아들이고, 함수로부터 반환할 수 있습니다.

Element (엘리먼트)

  • React 앱의 가장 작은 단위
  • React 엘리먼트는 일반 객체이며(plain object) 쉽게 생성할 수 있습니다.
  • 엘리먼트는 컴포넌트의 “구성 요소”로, 컴포넌트와는 다릅니다.
  • 엘리먼트는 불변객체입니다. 엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식이나 속성을 변경할 수 없습니다. 엘리먼트는 영화에서 하나의 프레임과 같이 특정 시점의 UI를 보여줍니다.
    • UI를 업데이트하는 유일한 방법은 새로운 엘리먼트를 생성하고 이를 
      ReactDOM.render() 로 전달하는 것
      입니다.

React DOM

  • React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트합니다.
  • React DOM은 모든 엘리먼트를 관리하므로, 루트(root) DOM 노드라고 부릅니다.
  • React 엘리먼트를 루트 DOM 노드에 렌더링하려면 ReactDOM.render()
    로 전달하면 됩니다.
  • React DOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교하고 DOM을 원하는 상태로 만드는데, 필요한 경우에만 DOM을 업데이트합니다.

Props (속성)

  • props는 읽기 전용입니다.
  • 자식이 부모의 state를 가져다쓰고 싶을 때는 props를 사용합니다.
  • 컴포넌트는 props를 수정해서는 안 됩니다.
  • 모든 React 컴포넌트는 자신의 props, 즉 입력값을 변경하는 것을 허용하지 않습니다.
    • 대신 state를 통해 위 규칙을 위반하지 않고 사용자 액션, 네트워크 응답 및 다른 요소에 대한 응답으로 시간에 따라 자신의 출력값을 변경할 수 있습니다.

State (상태)

  • 변수가 있음에도 굳이 state를 쓰는 이유는 무엇일까요?
    • state는 변경 가능한 변수입니다.
    • 변수는 변경시 html에 자동으로 렌더링이 되지 않습니다. 반면, state는 변경시 state를 쓴 html 부분이 자동으로 재렌더링 됩니다.
    • 따라서 자주 변경될 것 같은 html 부분은 state로 만들어 놓아야합니다.
  • 직접 State를 수정하지 마세요. 대신에 setState()를 사용합니다.
    • state는 등호로 변경 금지!! (html에 반영이 안됨)
    • setState 함수, state 변경용 함수로 변경을 해야 html 재렌더링이 됩니다.
  • array/object와 state
    • array, object를 담은 변수는 데이터를 담는 것이 아니라, 어디에 들어있는지 알려주는 화살표만 저장됩니다. (reference data type)
      • 데이터는 RAM에 저장
    • array와 object는 원본을 수정하지 않고, 보존하는 것이 좋아요.
      • 원본을 영구적으로 수정한 경우, 다시 되돌리기 어렵기 때문!
    • 결론: copy본을 만들어서 copy본을 수정합니다.
  • state 변경 함수 setState() 동작 원리
    • 소괄호 안에 넣은 걸 기준으로 기존 state를 변경합니다.
    • 기존 state와 신규 state를 비교해서 같은 경우 변경하지 않아요.
      • 기존 state == 신규 state → false가 나와야 변경(true는 변경X)
      • 이유: 리소스 절약을 위해서
    • array, object의 경우 화살표(위치)만 저장되므로 그대로 copy하면 화살표가 copy됩니다.
      • 변수1 == 변수2 의 화살표를 비교하면 true가 나옴
    • 따라서 copy를 할때 spread operator를 사용해서 copy합니다.
      • let 변수1 = […변수2]
        • copy의 경우 화살표도 달라지고, 독립적인 array가 나오기 때문!

Rendering (렌더링)

  • React에서 렌더링은 본질적으로 UI 로직과 연결되어 있습니다. UI 로직은 아래와 같습니다. (아래 방식들이 실행되는 경우 렌더링이 실행됩니다.)
    • 이벤트가 처리되는 방식
    • 시간에 따라 state가 변하는 방식
    • 화면에 표시하기 위해 데이터가 준비되는 방식 등

Conditional Rendering (조건부 렌더링)

if문

  • if문을 활용해 true/false 값에 따라 렌더링 할 부분을 정할 수 있습니다.엘리먼트 변수
    • 변수에 엘리먼트를 저장하여, 조건에 따라 엘리먼트를 출력할 수 있습니다. 이 경우 다른 부분은 변하지 않고, 컴포넌트의 일부인 엘리먼트만 조건부로 렌더링합니다.

논리 && 연산자로 If를 인라인으로 표현하기

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      **{unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }**
    </div>
  );
}
  • true/false && expression
    • 조건이 true일때 && 뒤의 엘리먼트가 출력됩니다.
    • 조건이 false라면 React는 무시하고 건너뜁니다.

조건부 연산자(삼항 연산자)로 If-Else구문 인라인으로 표현하기

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}
  • 가독성이 떨어질 수 있어 짧은 구문에 추천합니다.

만약 컴포넌트를 렌더링하지 않으려면? (없애려면)

  • 가끔 다른 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있을 수 있습니다.
  • 이때는 렌더링 결과를 출력하는 대신 null을 반환하면 해결할 수 있습니다.
function WarningBanner(props) {
  **if (!props.warn) {
    return null;
  }
}**

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);

Lists (리스트)

배열을 엘리먼트 리스트로 만드는 방식

  • 엘리먼트 모음을 만들고 중괄호 {}를 이용하여 JSX에 포함 시킬 수 있습니다.
  • JavaScript map() 함수를 사용하여 배열을 반복 실행합니다. 그리고 각 항목에 대한 엘리먼트 반환 및 엘리먼트 배열의 결과를 저장합니다.

기본 리스트 컴포넌트

  • 일반적으로 컴포넌트 안에서 리스트를 렌더링합니다.
  • 그럴 경우, 일반적으로 순서 없는 엘리먼트 리스트를 출력하는 컴포넌트로 리팩토링할 수 있습니다.
  • 이 코드를 실행하면 리스트의 각 항목에 key를 넣어야 한다는 경고가 표시됩니다. “key”는 엘리먼트 리스트를 만들 때 포함해야 하는 특수한 문자열 어트리뷰트입니다.

key (키)

  • Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다.
  • key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
  • Key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다.
  • 대부분의 경우 데이터의 ID를 key로 사용합니다.
  • 렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 인덱스를 key로 사용할 수 있습니다.
    • 항목의 순서가 바뀔 수 있는 경우 key에 인덱스를 사용하는 것은 권장하지 않습니다.
const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

'TIL' 카테고리의 다른 글

TIL-24.05.10  (0) 2024.05.10
TIL-24.05.09  (0) 2024.05.10
TIL-24.05.07  (0) 2024.05.07
TIL-24.05.03  (0) 2024.05.03
TIL-24.05.02  (0) 2024.05.02