JavaScript 및 React의 메모이제이션

소개



메모이제이션은 흥미로운 개념이며 모든 Javascript 개발자가 그것에 매료되고 친숙해야 한다고 생각합니다.

나는 이 주제를 다음과 같은 방식으로 살펴볼 것입니다: WHAT, WHY 및 HOW

1. 메모이제이션이란?



메모이제이션이라는 단어를 처음 보았을 때 내 머릿속에 떠오른 것은 암기였다. 나는 혼란스러웠다! 자바스크립트가 나를 대신해 무언가를 암기하고 기억하는 방법(자바스크립트에 기본적으로 기계 학습의 형태가 있는지 생각하고 있었습니다), 메모이제이션의 개념에 깊이 들어가보니 자바스크립트가 암기하도록 돕는 것이 전부라는 것을 이해했습니다. 이전 계산.

즉, 메모이제이션은 이전 계산 결과를 기억하여 반복적이고 비용이 많이 드는 계산 속도를 높이는 데 도움이 되는 최적화 기법입니다.

2. 왜 메모이제이션인가?



이 기술은 계산을 효율적이고 빠르게 만드는 데 중점을 둡니다. 비용이 많이 드는 계산이 수행되면 메모이제이션을 사용하여 결과를 예를 들어 저장할 수 있습니다. 필요할 때 캐시하고 검색하므로 다시 계산할 필요가 없습니다.

메모이제이션을 통해 이 모든 것을 얻을 수 있으며, 또한 효율적인 계산, 최적화 및 더 빠른 계산을 얻을 수 있습니다(이전에 수행된 작업을 건너뛰기 때문에).

3. 메모이제이션은 어떻게 구현하나요?



자바스크립트에서?



메모이제이션 구현은 메모이제이션 콜백에 함수를 전달하는 것입니다.

const multiplyBy10 = (num: number) => num * 10;
console.log('Simple call', multiplyBy10(3));

/**
 * 
 * Explanation: a simple memoize function that takes in a function
 * 
 * @param fn a function to be memoized or used to perform computation
 * @returns a memoized function
 */

const memoize = (fn: Function) => {
  let cache = {};

  return (...args) => {
    let num = args[0];  // just taking one argument here

    if (num in cache) {
      console.log('Fetching from cache');
      return cache[num];
    } else {
      console.log('Calculating result');
      let result = fn(num);
      cache[num] = result;
      return result;
    }
  }

}

// creating a memoized function for the 'multiplyBy10' pure function

const memoizedAdd = memoize(multiplyBy10);
console.log(memoizedAdd(3));  // calculated
console.log(memoizedAdd(3));  // cached
console.log(memoizedAdd(4));  // calculated
console.log(memoizedAdd(4));  // cached



코드 참조에 대한 Codegrepper & Agreeable Armadillo 덕분에



반응 중



메모이제이션을 구현하는 방법에는 여러 가지가 있으며 이는 수행해야 할 작업을 기반으로 합니다.
  • 컴포넌트 사용 React.memo()
  • 함수를 메모하려면 React.useCallback()을 사용하십시오.
  • 비용이 많이 드는 함수의 결과를 메모하려면 React.useMemo()를 사용하십시오.

  • 이 메서드는 올바른 방식으로 사용되는 경우 반응에서 불필요한 재렌더링을 방지합니다.

    React.memo() 이해하기




    /**
     * Explanation: 
     *  this function accept a name and render a styled version of it
     * 
     * @param name
     * @returns JSX.Element (styled version of the name)
     **/
    import React from 'react';
    
    function RenderName({ name }: string) {
        return <span className="text-red-500">{name}</span>
    }
    
    export default React.memo(RenderName);
    
    


    Consider the component above(child-component) without the React.memo() higher order component (HOC) we'll have issues with re-rendering when the name passed to the RenderName component are the same; but React.memo() HOC helps to prevent this unnecessary re-renders



    NB: memo는 하위 구성 요소에 전달되는 함수를 최적화하지 않으므로 React.useCallback()이 필요합니다.

    React.useCallback() 이해하기




    /**
     * Explanation:
     * a password field that handles users password 
     * and provides a toggle for the password
     *  
     * @returns JSX.Element (a styled password field)
     */
    import React from 'react';
    import eye from 'images/eye.svg';
    import eyeClose from 'images/eye-close.svg';
    
    function PasswordInput() {
      const [show, setShow] = React.useState<boolean>(false);
      const toggleSecret = React.useCallback(() => setShow(x => !x), []);
    
      return (
        <div className="h-8 flex items-center">
          <input type="password" className="..." placeholder="Enter Password" />
    
          <button onClick={toggleSecret}>
            <img src={show ? eyeClose : eye} alt="toggle secret" />
          </button>
        </div>
      );
    }
    
    export default PasswordInput;
    
    


    with React.useCallback() the toggleSecret() function is memoized and whenever you click this the toggle button it doesn't cause a re-render there by increasing optimization.
    Note: we passed the arrow function to the React.useCallback(). the arrow function is:
    () => setShow((x) => !x)
    React.useCallback() also helps to prevent re-rendering when a function is being passed down to a child component, This is done by 'keeping' the function passed to the child component while the parent component re-render.



    React.useMemo() 이해하기




    /**
     * Explanation:
     * The code demonstrates how to create a DynamicTable using React's useMemo() function.
     * The DynamicTable component is a wrapper around the Table component.
     * The DynamicTable component is responsible for creating the columns and data for the Table component.
     * 
     * @param {values: Record<string, string>[] | null}
     * @returns returns a JSX.Element(Table)
     */
    
    import React, { useMemo } from 'react';
    import Table, { ColumnsProps } from './Table';
    
    interface DynamicTableType {
      values: Record<string, string>[] | null;
    }
    
    const DynamicTable = ({ values }: DynamicTableType): JSX.Element => {
      const columns: ColumnsProps[] = useMemo(() => {
        if (!values) return [];
        const keys = Object.keys(values?.[0]);
    
        const result = [];
    
        for (let index = 0; index < keys.length; index++) {
          const element = keys[index];
          result.push({
            Header: element?.replace('_', ' '),
            accessor: element,
          });
        }
    
        return result;
      }, [values]);
    
      const data: Record<string, string>[] = useMemo(() => {
        if (!values) return [];
        const result: Record<string, string>[] = [];
    
        for (let index = 0; index < values.length; index++) {
          const element = values[index];
          result.push(element);
        }
        return result;
      }, [values]);
    
      return <Table columns={columns} data={data} showSearch={false} />;
    };
    
    export default DynamicTable;
    
    


    현재 작업 중인 오픈 소스 프로젝트에서 추출, 확인github

    The whole idea behind React.useMemo() is similar to that of React.useCallback(); but in React.useMemo() the result returned from the function calculation is being cached, so you dont have to repeat such expensive calculation (provided that your dependent array of the useMemo does not change). In the above example, columns & data are the memoized value.



    결론



    대체로 최적화는 엔지니어로서 관심을 가져야 하는 부분이며 캐싱과 같은 간단한 기술은 재렌더링/최적화 문제 등을 방지하는 데 도움이 될 수 있습니다. 메모이제이션은 비용이 많이 드는 계산을 처리할 때만 필요합니다.

    I am available for technical talks on data-structure, algorithms, javascript, react and react-native; you can reach out to me via or email

    I will also start a youtube channel soon to highlight my jouney with data-structure and algorithms, In the channel, I will be solving some leetcode questions and anyother interview materials I lay my hands on. watch out 😊



    각주



    이 튜토리얼을 확인해 주셔서 감사합니다. (좋아요와 댓글을 달아주세요)
    blog에서 내 다른 글을 확인할 수도 있습니다.

    질문, 피드백 또는 의견이 있으면 알려주십시오.

    email github에서 나와 연결할 수 있습니다.

    나에게 연락할 수도 있습니다(저는 React-Native 및 React J를 합니다)email

    좋은 웹페이지 즐겨찾기