카테고리 없음

react정리7

jkkll 2022. 7. 28. 21:32

리엑트

사용자 인터페이스 구축을 위한 자바스크립트 라이브러리 리엑트의 핵심은 컴포넌트
효과적인 사용자 인터페이스 구축을 위해 컴포넌트를 사용
컴포넌트관리, 상태 객체 관리, 다른 객체의 상태와 컴포넌트가 바뀌어야 하는지 확인, 컴포넌트 변경 전후의 상태확인 하는 라이브러리, 컨텍스트관리
props 관리 props는 컴포넌트에 전달하는 데이터로 컴포넌트 구성을 가능하게 해주고 부모-자식 컴포넌트간의 통신을 연결해준다
props, 상태 또는 컨텍스트가 변경되면 이런 것들을 사용하는 컴포넌트 역시 리엑트를 통해 변경되고
리엑트는 이 컴포넌트가 화면에 새로운 것을 표시하는지 확인한다

 

실제DOM과의 통신

 

리엑트DOM 웹에 대한 인터페이스 브라우저의 일부인 실제 DOM에 대한 작업을 한다
실제 HTML요소들을 화면에 표시해준다
새로운 화면과 새로운 컴포넌트 표시할 수 있게 해준다

가상DOM이라는 개념 사용
상태가 업데이트 되면 이 정보가 리엑트DOM으로 전달되어 갱신 전후의 상태차이 인식하고 리엑트가 컴포넌트 트리를 통해 구성한 가상 스냅샷인 가상DOM과 일치하도록 실제 DOM을 조작하는 방법을 알 수 있게 한다
컴포넌트는 상태, props, 컨텍스트가 변경될 때 재평가된다 이때 리엑트는 함수를 다시 실행한다
실제 DOM은 리엑트가 구성한 컴포넌트이전상태와 트리, 현재상태간의 차이점기반으로 변경이 필요할 때만 업데이트 된다
예를 들어 div태그 안에 h1만 있는 경우에 p태그를 추가했을 때 리엑트는 두 스냅샷간이 차이점이
p태그임을 확인하고 이를 리엑트DOM에 보고하면 리엑트DOM은 실제 DOM을 업데이트하고
새로운 문장을 집어넣는다 전체를 랜더링 하지 않는다 h1이나 div요소는 건드리지 않고 h1요소 다음 p태그만을 추가한다

컴포넌트 업데이트

import React, { useState } from "react";

//리엑트는 상태나 props, 컨텍스트 변경시에만 함수를 재실행, 재평가
import "./App.css";
import Button from "./components/UI/Button/Button";

function App() {
  const [showParagraph, setShowParagraph] = useState(false);
  //기존값의 반대값 !
  //실제 DOM을 통한 업데이트는 가상 스냅샷 간의 차이점만 반영된다 다른 것은 그대로
  const toggleParagraphHandler = () => {
    setShowParagraph((prevShowParagraph) => !prevShowParagraph);
  };
  return (
    <div className="app">
      <h1>Hi there!</h1>
      {showParagraph && <p>This is new!</p>}
      <Button onClick={toggleParagraphHandler}>Show Paragraph!</Button>
    </div>
  );
}

export default App;

자식 컴포넌트 재평가

DemoOutput.js

import React from "react";

//props를 통해 받은 데이터 기반으로 랜더링
//prop.show 값이 true라면 This is new 아니라면 빈 문자열을 랜더링

//props.show를 먼저 입력했기 때문에 App.js에 가서
//DemoOutput을 import 하고 return에 속성을 추가해준다
const DemoOutput = (props) => {
  return <p>{props.show ? "This is new!" : ""}</p>;
};

export default DemoOutput;

App.js

import React, { useState } from "react";

//상태나 props, 컨텍스트 변경시에만 함수를 재실행, 재평가
import "./App.css";
import Button from "./components/UI/Button/Button";
import DemoOutput from "./components/UI/Button/Demo/DemoOutput";

function App() {
  const [showParagraph, setShowParagraph] = useState(false);
  const toggleParagraphHandler = () => {
    setShowParagraph((prevShowParagraph) => !prevShowParagraph);
  };

  return (
    <div className="app">
      <h1>Hi there!</h1>
      <DemoOutput show={showParagraph} />
      <Button onClick={toggleParagraphHandler}>Show Paragraph!</Button>
    </div>
  );
}

export default App;

useMemo

인자로 들어간 컴포넌트에 어떤 props가 입력되는지 확인하고
입력되는 모든 props의 신규 값 확인 뒤 기존 값과 비교하도록 전달
 props의 값이 바뀐 경우에만 컴포넌트를 재실행 및 재평가

import React from "react";
import MyParagraph from "./MyParagraph";

const DemoOutput = (props) => {
  console.log("DemoOutput RUNNING");
  return <MyParagraph>{props.show ? "This is new!" : ""}</MyParagraph>;
};
//특정상황의 경우 특정컴포넌트 재실행 지시 useMemo
//함수형 기반의 컴포넌트에서만 사용가능
//props가 바뀌었는지 확인할 컴포넌트 지정 후에 React.memo추가

export default React.memo(DemoOutput);

https://academind.com/tutorials/reference-vs-primitive-values

useCallback

함수를 저장하고 재사용할 수 있다

let obj1 = {};

let obj2 = {};

자바스크립트에서 obj1 === obj2 는 false

obj1 = obj2 메모리 안의 같은 위치를 가리키고 있다면 같은 객체로 간주 obj1 === obj2 true

이것이 useCallback이 하는 일로 선택한 함수를 리엑트의 내부 저장 공간에 저장해서 함수 객체가 실행될 때마다 재사용할 수 있게 된다

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

import "./App.css";
import Button from "./components/UI/Button/Button";
import DemoOutput from "./components/UI/Button/Demo/DemoOutput";

function App() {
  const [showParagraph, setShowParagraph] = useState(false);

  //useCallback 사용하려는 함수를 감싸준다 지정된 함수를 반환한다
  //App함수가 다시 실행되면 useCallback이 리엑트가 저장한 함수를 찾아서 같은 함수 객체를 재사용한다
  //따라서 어떤 함수가 절대 변경되면 안된다면 useCallback을 사용해 함수를 저장하면 된다
  //useCallback은 useEffect와 마찬가지로 두번째 인자가 필요, 배열이어야 한다
  //useCallback에 대한 의존성 배열
  //여기서의 배열은 toggleParagraphHandler에 저장하려고 하는 이 콜백함수는 절대 변경되지 않을 것이라고 리엑트에 알려주는 배열
  //다시 랜더링 되어도 항상 같은 함수 객체가 사용되게끔 한다
  //이를 저장하고 새로고침하면 button문구는 처음 한 번 보이고 그 뒤로 나타나지 않는다
  //우리가 전달한 모든 props값이 비교 가능하게 전달했기 때문에 react.memo가 역할을 수행할 수 있다
  //toggleParagraphHandler객체가 useCallback 덕분에 메모리 안에서 항상 같은 객체임을 보증하기 때문

  const toggleParagraphHandler = useCallback(() => {
    setShowParagraph((prevShowParagraph) => !prevShowParagraph);
  }, []);


  return (
    <div className="app">
      <h1>Hi there!</h1>
      <DemoOutput show={showParagraph} />
      <Button onClick={toggleParagraphHandler}>Show Paragraph!</Button>
    </div>
  );
}

export default App;