[react-native] Hooks(4) useMemo

    반응형
    이 글은 <처음 배우는 리애트 네이티브 (김범준, 한빛미디어)>를 읽고 이해한 바를 바탕으로 작성되었습니다.
     

    GitHub - Alchemist85K/my-first-react-native: [한빛미디어] 처음 배우는 리액트 네이티브 소스 코드입니다.

    [한빛미디어] 처음 배우는 리액트 네이티브 소스 코드입니다. . Contribute to Alchemist85K/my-first-react-native development by creating an account on GitHub.

    github.com

     

    💡useMemo

    useMemo는 동일한 연산의 반복 수행을 제거해서 성능을 최적화하는데 사용된다.

    useEffect와 똑같이, 첫 번째 파라미터에는 조건 만족 시, 실행 될 함수를 작성하고, 두 번째 파라미터에는 함수가 실행될 조건을 배열로 전달한다. 배열 안에 작성한 값에 변화가 있는 경우에만 첫 번째 파라미터로 전달된 함수가 실행된다.

    💡useMemo를 사용하지 않을 때,

    import React, { useState } from 'react';
    import styled from 'styled-components/native';
    import Button from './Button';
    
    const StyledText = styled.Text`
        font-size: 24px;
    `;
    
    const getLength = text => {
        console.log(`Target Text: ${text}`);
        return text.length;
    }
    
    const leist = ['JavaScript', 'Expo', 'Expo', 'React Native'];
    
    let idx = 0;
    const Length = () => {
        const [text, setText] = useState(list[0]);
        const [length, setLength] = useState('');
        const _onPress = () => {
            setLength(getLength(text));
            ++idx;
            if (idx < list.length) setText(list[idx]);
        };
    
        return (
            <>
            <StyledText>Text: {text}</StyledText>
            <StyledText>Length: {length}</StyledText>
            <Button title='Get Length' onPress={_onPress} />
            </>
        );
    };
    
    export default Length;
    
    /* src/components/Length.js */

    문자열 4개를 넣은 list를 생성하고,
    useState를 사용해서 상태변수 text, length와 세터함수 setText, setLength를 생성한다.
    그리고 Button의 onPress로 전달한 _onPress를 생성하고, onPress에서는 text의 길이를 구하는 함수를 setLength의 파라미터로 넘겨서 length 변수 값을 변경한다. 그리고 인덱스를 하나씩 증가시켜서 단어를 바꿔준다.

    import React, {useState} from 'react';
    import styled from 'styled-components/native';
    import Button from './components/Button';
    import Length from './components/Length';
    
    const Container = styled.View`
        flex: 1;
        background-color: #fff;
        justify-content: center;
        align-items: center;
    `;
    
    const App = () => {
        const [isVisible, setIsVisible] = useState(true);
    
        return (
            <Container>
                <Length />
            </Container>
        );
    };
    
    export default App;
    
    /* src/App.js */

    하지만, console에서 찍히는 것을 보면 알겠지만,
    Expo는 같은 문자열임에도 불구하고 버튼을 누르면 똑같은 연산이 반복되고,
    배열의 맨 마지막 값인 React Native는 버튼을 누를 때마다 계속 같은 연산이 반복된다.

    이렇게 값의 변경이 없음에도 불구하고 쓸데없이 계속 함수가 호출될 때, useMemo를 사용하면 값에 변화가 있는 경우만 함수를 호출할 수 있다.

    💡useMemo를 사용하면,

    import React,  {useState, useMemo} from 'react';
    import styled from 'styled-components/native';
    import Button from './Button';
    
    const StyledText = styled.Text`
        font-size: 24px;
    `;
    
    const getLength = text => {
        console.log(`Target Text: ${text}`);
        return text.length;
    }
    
    const list = ['JavaScript', 'Expo', 'Expo', 'React Native'];
    
    let idx = 0;
    const Length = () => {
        const [text, setText] = useState(list[0])
    
        const _onPress = () => {
            ++idx;
            if (idx < list.length) setText(list[idx]);
        };
    
        const length = useMemo(() => getLength(text), [text]);
        
        return (
            <>
                <StyledText>Text: {text}</StyledText>
                <StyledText>Length: {length}</StyledText>
                <Button title = 'GetLength' onPress = {_onPress} />
            </>
        );
    };
    
    export default Length;
    
    /* src/components/Length.js */

    useState가 아닌 useMemo를 사용해 length를 생성하였다.

    const length = useMemo( () => getLength(text), [text]); 

    두번째 파라미터로 text를 배열로 전달하여 text의 값이 변경될 때만 getLength(text) 함수가 호출되도록 하였다.

    useMemo를 사용하지 않았을 때와는 다르게, 버튼을 아무리 눌러도, Expo의 문자열을 계산하는 함수도 한번만, React Native의 문자열을 계산하는 함수도 딱 한번만 호출된다.

    이렇게 useMemo를 이용하면 중복된 연산을 방지함으로써 성능을 최적화할 수 있다!

    반응형

    'JavaScript > React-Native' 카테고리의 다른 글

    [react-native] Stack Navigation  (3) 2021.08.25
    [react-native] Context API  (1) 2021.08.23
    [react-native] Hooks(3) useRef  (0) 2021.08.22
    [react-native] Hooks(2) useEffect  (0) 2021.08.21
    [react-native] Hooks(1) useState  (0) 2021.08.21

    댓글