React.메모·useCallback() 정리를 해봤습니다.

49903 단어 ReactTypeScripttech

이거 뭐야?


리액트 초보자가'리액트.memo'·'useCallback()'으로 학습 내용을 정리한 글이다.
이번에는 계수 기능 적용의 경우'React.memo','useCallback()'을 시행해 봤다.

React.memo·useCalleback()는 무엇입니까?


'React.memo','useCallback()'을 사용하면 불필요한 재렌더링을 방지하고 성능을 높일 수 있습니다.반대로 이런 앱을 사용하지 않아도 앱 자체가 작동한다.

React.memo

  • 상위 구성 요소
  • 이전의 props와 새로운 props를 비교하여 값을 검사하고, 값이 같으면 건너뛰고 다시 나타나고, 값이 같지 않으면 다시 나타난다
  • https://ja.reactjs.org/docs/higher-order-components.html
    React.문법
    React.memo(親コンポーネントからpropsを受け取る子コンポーネント)
    

    useCallback()

  • 함수 자체를 기록하는 연결에 사용
  • useCallback()에 기록된 호출 함수는 React입니다.mps로memo에 기록된 하위 구성 요소로 전달하여 필요하지 않은 리셋을 건너뛸 수 있음
  • useCallback () 의 구문
    useCallback(コールバック関数,[コールバック関数が依存している要素の配列])
    
    !
    두 번째 파라미터에 의존하는 그룹을 두 번째 파라미터에 전달하면, 의존 그룹이 변할 때만 호출 함수를 다시 만들 수 있습니다.

    개발 환경

  • OS: macOS Monteerey 버전 12.3.1
  • 언어: TypsScript
  • 장서:React
  • 환경 구조


    이번에는 노드를 설치하는 전제로 진행한다.
    구축 환경의 디렉터리로 이동하여 "Create-React-App"을 사용하여 React의 응용 환경을 구축합니다.
    $ npx [email protected] react-typescript-app --template typescript
    
    https://create-react-app.dev/docs/getting-started
    !
    노드 버전은 14개 이상이 필요합니다.
    내 환경에서crea-react-app 버전을 지정하지 않으면 다음과 같은 오류가 발생합니다.0.1이 지정되었습니다.(Create-React-Appliance 를 제거한 후에도 같은 오류가 발생했습니다.)
    You are running `create-react-app` 5.0.0, which is behind the latest release (5.0.1).
    
    We no longer support global installation of Create React App.
    
    Please remove any global installs with one of the following commands:
    - npm uninstall -g create-react-app
    - yarn global remove create-react-app
    
    The latest instructions for creating a new app can be found here:
    https://create-react-app.dev/docs/getting-started/
    

    파일 구성


    react-typescript-app
    ├── README.md
    ├── node_modules
    ├── package.json
    ├── .gitignore
    ├── ts.config.json
    ├── public
    │   ├── favicon.ico
    │   ├── index.html
    │   ├── logo192.png
    │   ├── logo512.png
    │   ├── manifest.json
    │   └── robots.txt
    └── src
            ├──components
        │	├──Button
        │   │  ├──Button.tsx
        │   │  └──Button.module.scss
        │   ├──Counter
        │   │  ├──Counter.tsx
        │	│  └──Counter.module.scss
        │	└──Title
        │      ├──Title.tsx
        │	   └──Title.scss
        ├── App.css
        ├── App.js
        ├── App.test.js
        ├── index.css
        ├── index.js
        ├── logo.svg
        ├── serviceWorker.js
        └── setupTests.js|
    

    이루어지다


    이번에는 Sass 스타일링, 설치node-sass입니다.
    $npm install node-sass
    
    모 어셈블리
    App.tsx
    import React, { useState } from "react";
    import classes from "./App.module.scss";
    import Title from "./components/Title/Title";
    import Counter from "./components/Counter/Counter";
    import Button from "./components/Button/Button";
    
    function App() {
      const [count, setCount] = useState<number>(0);
      const handleCountUp = () => {
        setCount((preCount) => preCount + 1);
      };
    
      const handleCountDown = () => {
        setCount((preCount) => preCount - 1);
      };
    
      return (
        <div className={classes.app}>
          <Title titleText="現在の数字"></Title>
          <Counter count={count}></Counter>
          <div className={classes.buttonsWrapper}>
            <Button buttonText="+1" onClick={handleCountUp} />
            <Button buttonText="-1" onClick={handleCountDown} />
          </div>
        </div>
      );
    }
    
    export default App;
    
    서브어셈블리
    componets/Title/Title.tsx
    import React from "react";
    
    type Props = {
      titleText: string;
    };
    
    const Title: React.VFC<Props> = ({ titleText }) => {
      console.log(`Title:${titleText}`);
      return <h2>{titleText}</h2>;
    };
    
    export default Title;
    
    components/Counter/Counter.tsx
    import React from "react";
    
    type Props = {
      count: number;
      countText: string;
    };
    
    const Counter: React.VFC<Props> = ({ countText, count }) => {
      console.log(`${countText}ボタンを押した回数:${count}`);
      return (
        <h2>
          {countText}を押した回数:{count}</h2>
      );
    };
    
    export default Counter;
    
    components/Button/Button.tsx
    import React from "react";
    import classes from "./Button.module.scss";
    
    type Props = {
      buttonText: string;
      onClick: () => void;
    };
    
    const Button: React.VFC<Props> = ({ buttonText, onClick }) => {
      console.log(`${buttonText}ボタンをクリック`);
      return (
        <div className={classes.container}>
          <button className={classes.button} onClick={onClick}>
            {buttonText}
          </button>
        </div>
      );
    };
    
    export default Button;
    
    스타일링
    App.module.scss
    .app {
      margin-top: 40px;
      text-align: center;
      font-family: "Courier New", Courier, monospace;
      .itemsWrapper {
        .items {
          margin-left: auto;
          margin-right: auto;
          width: 70%;
        }
        .countsWrapper {
          display: flex;
          justify-content: space-around;
        }
        .buttonsWrapper {
          display: flex;
          justify-content: space-around;
          .buttons {
            text-align: center;
          }
        }
      }
    }
    
    components/Button/Button.module.scss
    .container {
      margin-left: 10px;
      .button {
        background-color: gray;
        color: white;
        font-weight: bold;
        width: 100px;
        padding: 10px 20px;
        font-size: 24px;
        cursor: pointer;
        border: none;
        border-radius: 10px;
      }
    }
    
    완성 화면

    그러면 A 버튼을 눌렀을 때의 기록을 확인하면서 리액트를 진행한다.memo와useCallback()을 설치할 때와 설치하지 않을 때의 차이를 살펴봅시다.

    React.memo를 설치하지 않을 경우


    A버튼을 눌러보세요.

    모든 서브어셈블리가 다시 렌더링되었음을 알 수 있습니다.

    React.memo가 설치된 경우


    React.memo를 하위 구성 요소에 설치합니다.
    components/Title/Title.tsx
    + const Title: React.VFC<Props> = React.memo(({ titleText }) => {
    +  console.log(`Title:${titleText}`);
    +  return <h2>{titleText}</h2>;
    + });
    - const Title: React.VFC<Props> = { titleText }) => {
    -  console.log(`Title:${titleText}`);
    -  return <h2>{titleText}</h2>;
    - };
    
    components/Counter/Counter.tsx
    + const Counter: React.VFC<Props> = React.memo(({ countText, count }) => {
    + console.log(`${countText}ボタンを押した回数:${count}`);
    + return (
    + <h2>
    +     {countText}を押した回数:{count}+  </h2>
    + );
    + });
    - const Counter: React.VFC<Props> = ({ countText, count }) => {
    - console.log(`${countText}ボタンを押した回数:${count}`);
    - return (
    -    <h2>
    -      {countText}を押した回数:{count}-    </h2>
    -  );
    - };
    
    components/Button/Button.tsx
    + const Button: React.VFC<Props> = React.memo(({ buttonText, onClick }) => {
    + console.log(`${buttonText}ボタンをクリック`);
    + return (
    +   <div className={classes.container}>
    +     <button className={classes.button} onClick={onClick}>
    +       {buttonText}
    +     </button>
    +   </div>
    +  );
    + });
    - const Button: React.VFC<Props> = ({ buttonText, onClick }) => {
    - console.log(`${buttonText}ボタンをクリック`);
    - return (
    -    <div className={classes.container}>
    -      <button className={classes.button} onClick={onClick}>
    -        {buttonText}
    -      </button>
    -    </div>
    -  );
    - };
    
    A버튼을 눌러보세요.

    Title 구성 요소 및 B의 Couter 구성 요소가 렌더링되지 않았습니다.리액션입니다.메모 중성자 구성 요소가 기록되어 있기 때문에 지난번과 이번 Porps의 차이는 변경되지 않은 상황에서 하위 구성 요소는 렌더링되지 않습니다.
    그러나 B의 Buttton 어셈블리가 렌더링되고 있습니다.앱 어셈블리로 재현할 때'handle CountB'함수가 재제작돼 버튼 어셈블리로 전달되는'onClick'이 지난번'onClick'과 다르게 렌더링됐기 때문이다."handle CountB"함수를 다시 만들지 않기 위해서는useCallback을 사용하여 "handle CountB 함수"를 표시해야 합니다.

    React.memo·useCallback()이 설치된 경우


    useCallback을 사용하여 App 구성 요소의 함수를 기록합니다.
    App.tsx
    + import React, { useCallback, useState } from "react";
    - import React, { useState } from "react";
    
    + const handleCountA = useCallback(() => {
    +  setCountA((preCount) => preCount + 1);
    + }, []);
    - const handleCountA = () => {
    -    setCountA((preCount) => preCount + 1);
    -  };
    
    + const handleCountB = useCallback(() => {
    +   setCountB((preCount) => preCount + 1);
    + }, []);
    - const handleCountB = () => {
    -   setCountB((preCount) => preCount + 1);
    - };
    
    A버튼을 눌러보세요.

    A의 Buton 구성 요소만 표시됩니다.
    이상입니다.
    끝까지 읽어주셔서 감사합니다.
    잘못이 있으면 지적해 주세요.

    참고서


    https://qiita.com/soarflat/items/b9d3d17b8ab1f5dbfed2
    https://www.amazon.co.jp/기초부터 배우기 - React-Hooks-asakohattori/dp/486354359X

    좋은 웹페이지 즐겨찾기