React

  • React 는 웹 프레임워크로, 자바스크립트 라이브러리의 하나로서 사용자 인터페이스를 만들기 위해 사용된다.
  • 클라이언트와 인터랙션이 자주 발생하고, 이에 따라 동적으로 UI 를 표현해야된다면, 이벤트, DOM을 조작하는 규칙이 다양해질것이고, 유지보수가 까다로워진다
  • 리액트는 어떠한 상태가 바뀌었을때, 그 상태에 따라 DOM 을 어떻게 업데이트 할 지 규칙을 정하는 것이 아니라, 재랜더링 하는 아이디어를 기반으로 개발되었다

ref) https://react.vlpt.us/basic/01-concept.html

React의 특징

  1. Component 기반 구조

    • Component : 리액트로 만들어진 앱을 이루는 최소한의 단위
    • 컴포넌트를 통해 UI를 재사용 가능한 개별적인 여러 조각으로 나눌 수 있다
    • 컴포넌트는 데이터(props)를 입력받아 View(state) 상태에 따라 DOM Node를 출력하는 함수.
      • “props”라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.
    • 컴포넌트 이름은 항상 대문자로 시작한다(리액트는 소문자로 시작하는 컴포넌트를 DOM태그로 취급하기 떄문)
    • 클래스형 컴포넌트와 함수형 컴포넌트가 있다
      • 과거 클래스형 컴포넌트는 함수형 컴포넌트와 다르게 state, lifeCycle 관리가 가능했지만
      • 현재는 함수형 컴포넌트에서도 Hook을 통해 state 및 lifeCycle 관리가 가능해 지면서 자원효율성, 사용성이 좋은 함수형 컴포넌트가 일반적으로 사용되고 있다.
  2. SPA(Single Page Application)

    • 하나의 html 페이지와 애플리케이션 실행에 필요한 모든 자산(javascript, css)를 로드하는 애플리케이션을 의미
    • 서버로부터 새로운 페이지를 불러오지 않으므로 페이지가 다시 로드되지 않는다
    • 리액트를 사용하여 SPA를 만들 수 있지만 필수 사항은 아님
  3. Virtual DOM

    • Virtual DOM은 실제 DOM과 같은 내용을 담고 있는 복사본
    • 실제 DOM이 아닌 DOM의 트리구조를 Javascript객체 형태로 메모리 안에 저장해 둔다
    • 실제 DOM의 모든 속성을 공유하지만 문서를 직접 접근하여 조작하는 API를 제공하지는 않는다 ⇒ 때문에 가상돔에 접근하고 수정하는 것은 매우 가볍고 빠른 작업
    • 리액트는 항상 두개의 가상돔 객체를 가진다
      1. 렌더링 이전 화면 구조를 나타내는 Virtual DOM
      2. 렌더링 이후에 보이게 될 화면 구조를 나타내는 Virtual DOM
    • 리액트에서 Virtual DOM을 이용하여 렌더링 하는 과정
      • 리액트는 Stae가 변경될 때마다 Re-Renderding이 발생하고, 이 시점마다 새로운 내용이 담긴 가상돔이 생성된다.
      • 기존의 Virtual DOM과 새롭게 생성된 Virtual DOM을 비교해서 변화된 Element를 찾는다(Diffing) ⇒ Diffing은 효율적인 알고리즘을 사용해 진행되기 때문에 어떤 Element에 차이가 있는지를 매우 신속하게 파악할 수 있다.
      • 리액트는 이를 통해 차이가 발생한 부분만을 (브라우저상의) 실제 DOM에 적용한다(Reconciliation 재조정과정)
        • 변경된 모든 Element를 한번에 실제 DOM에 적용한다(Batch Update)
  4. Props and State

    • props 와 state는 리액트에서 데이터를 사용할 때 다루는 개념

    • react에서는 UI의 데이터는 반드시 props와 state로 관리되어야 한다

      • 데이터를 일관성 있게 다루기 위해서

      • react life cycle이 props와 state의 변경을 기준으로 화면을 갱신하기 때문

        SNPropsState
        1.Props are read-only.State changes can be asynchronous.
        2.Props are immutable.State is mutable.
        3.Props allow you to pass data from one component to other components as an argument.State holds information about the components.
        4.Props can be accessed by the child component.State cannot be accessed by child components.
        5.Props are used to communicate between components.States can be used for rendering dynamic changes with the component.
        6.Stateless component can have Props.Stateless components cannot have State.
        7.Props make components reusable.State cannot make components reusable.
        8.Props are external and controlled by whatever renders the component.The State is internal and controlled by the React Component itself.
    • Props

      • 컴포넌트에서 다른 컴포넌트(자식 컴포넌트)로 데이터를 전달하기 위해서 사용
      • 컴포넌트 내부에서 직접적으로 수정할 수 없다(읽기 전용) ⇒ 부모 컴포넌트에서 값을 변경할 수 있다
      • 부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하게 되면 부모 컴포넌트가 Re-Rendering 될 떄 자식 컴포넌트도 같이 Re-Rendering 된다
    • State

      • State는 한 컴포넌트 안에서 유동적인 데이터를 다룰 때 사용된다
      • 컴포넌트 안에서 데이터를 변경할 수 있다. ⇒ State는 한 컴포넌트의 상태(State)를 나타낸다.
      • state를 사용하기 위해 클래스형 컴포넌트를 사용하거나, 함수형 컴포넌트 사용시 훅(Hook)을 사용하여 state를 변경할 수 있다.
  5. JSX

    • JSX(JavaScript XML)는 Javascript에 XML을 추가한 확장한 문법이다.(공식적인 자바 스크립트 문법은 아님)
    • 브라우저에서 실행하기 전에 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환된다.
    • 하나의 파일에 자바스크립트와 HTML을 동시에 작성할 수 있어 편리하다(가독성이 우수하다)
    • 하나의 엘리먼트만 반환할 수 있다(반드시 부모 요소하나가 감싸는 형태여야 한다)
    • 자바스크립트 표현식을 사용한다 {...javascript expression...}
    • if문(for문) 대신 삼항 연산자(조건부 연산자) 사용
    • React DOM은 HTML attribute 대신 camelCase 프로퍼티 명명 규칙을 사용 한다.

회원 정보를 입력받아 목록에 추가하는 예제

  • App.js
    import {TotalUserInform} from "./components/total-user-inform";
    
    function App() {
    
      return (
        <div>
          <TotalUserInform/>
        </div>
      );
    }
    
    export default App;
  • total-user.inform.js
    import {UserInform} from "./user-inform";
    import {UserList} from "./user-list";
    import {useState} from "react";
    export const TotalUserInform = () => {
      const [userList, setUserList] = useState([]);
      const [prevUser, setPrevUser] = useState(null);
      const [user, setUser] = useState(null);
      if (user !== prevUser){
        setUserList([...userList, user])
        setPrevUser(user)
      }
      return (<div>
        <UserInform setUser={setUser}/>
        <UserList userList={userList}/>
      </div>)
    }
  • user-inform.js
    import React, {useState} from "react";
    
    export const UserInform = ({setUser}) => {
      const [inputIdValue, setInputIdValue] = useState("");
      const [inputPwValue, setInputPwValue] = useState("");
      const [inputNameValue, setInputNameValue] = useState("");
      const [inputAgeValue, setInputAgeValue] = useState("");
      const inputIdHandler = (event) => {
        setInputIdValue(event.target.value)
      };
      const inputPwHandler = (event) => {
        setInputPwValue(event.target.value)
      };
      const inputNameHandler = (event) => {
        setInputNameValue(event.target.value)
      };
      const inputAgeHandler = (event) => {
        setInputAgeValue(event.target.value)
      };
      const SubmitHandler = () => {
        setUser({
          id: inputIdValue,
          pw: inputPwValue,
          name: inputNameValue,
          age: +inputAgeValue
        })
      }
      return (
        <div>
          <label>Enter ID : </label>
          <input id={"id"} type="text" placeholder={"ID"} onChange={inputIdHandler}/><br/>
    
          <label>Enter PW : </label>
          <input id={"pw"} type="text" placeholder={"PW"} onChange={inputPwHandler}/><br/>
    
          <label>Enter Name : </label>
          <input id={"name"} type="text" placeholder={"Name"} onChange={inputNameHandler}/><br/>
    
          <label>Enter Age : </label>
          <input id={"age"} type="text" placeholder={"Age"} onChange={inputAgeHandler}/><br/>
    
          <button onClick={SubmitHandler}>Submit</button>
        </div>
      )
    }
  • user-list.js
    import React from "react";
    
    export const UserList = ({userList}) => {
      return (
        <table>
          <thead></thead>
          <tbody>
          {userList.map((user, index) => {
            return (
              <tr key={index} className="text-2xl">
                <td>id: {user.id}</td>
                <td>pw: {user.pw}</td>
                <td>name : {user.name}</td>
                <td>age: {user.age}</td>
              </tr>);
          })}
          </tbody>
          <tfoot></tfoot>
        </table>
      )
    }

0개의 댓글