useMemo를 이용해 최적화

장현욱(Artlogy)·2022년 8월 16일
1

React

목록 보기
12/24
post-thumbnail

useMemo 개요

Array.jsx

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

function User({ user, onRemove, onToggle }) {
    return (
        <div>
            {user.active ? (
                <b
                    onClick={() => {
                        onToggle(user.id);
                    }}
                    style={{ color: "green" }}
                >
                    {user.username}
                </b>
            ) : (
                <b
                    onClick={() => {
                        onToggle(user.id);
                    }}
                >
                    {user.username}
                </b>
            )}
            <span>({user.email})</span>
            <button onClick={() => onRemove(user.id)}>삭제</button>
        </div>
    );
}
const Array = () => {
    const [users, setUsers] = useState([
        {
            id: 1,
            username: "차가운 그녀",
            email: "cold_fish@gmail.com",
            active: true,
        },
        {
            id: 2,
            username: "기네스 맥주",
            email: "guness@gmail.com",
            active: false,
        },
        {
            id: 3,
            username: "나를잡아줘",
            email: "holdme@gmail.com",
            active: false,
        },
    ]);
    function countActiveUsers(users) {
        console.log("활성 사용자 수를 세는중...");
        return users.filter((user) => user.active).length;
    }
    const [inputs, setInputs] = useState({
        email: "",
        name: "",
    });
    const onChange = (e) => {
        const { value, name } = e.target;
        setInputs({ ...inputs, [name]: value });
    };
    const count = countActiveUsers(users);
    const onCreate = () => {
        // spread를 이용한 방법
        setUsers([
            ...users,
            {
                id: users.length + 1,
                email: inputs.email,
                username: inputs.name,
                active: false,
            },
        ]);
        //concat을 이용한 방법
        setUsers(
            users.concat({
                id: users.length + 1,
                email: inputs.email,
                username: inputs.name,
                active: false,
            })
        );
    };
    const onRemove = (id) => {
        // 해당 id(key)를 제외한 배열로 반환
        setUsers(users.filter((el) => el.id !== id));
    };
    const onToggle = (id) => {
        setUsers(
            users.map((el) =>
                el.id === id ? { ...el, active: !el.active } : el
            )
        );
    };
    return (
        <>
            <input
                name={"email"}
                placeholder="이메일"
                onChange={onChange}
            ></input>
            <input name={"name"} placeholder="이름" onChange={onChange}></input>
            <button onClick={onCreate}>등록</button>
            {users.map((el, idx) => (
                <>
                    <User
                        key={el.id}
                        user={el}
                        onRemove={onRemove}
                        onToggle={onToggle}
                    ></User>
                </>
            ))}
            <div>활성사용자 수 :{count}</div>
        </>
    );
};

export default Array;
위 코드를 실행시킨 후 
입력을 하면서 콘솔창을 살펴보면 입력을 할 때마다.
로그가 찍히는 걸 확인 할 수 있다.

위와 같은 결과가 나오는 이유는 랜더링되는 count가 값은 그대로지만 
input값이 바뀌기 때문에 계속 업데이트가 된다. 
때문에 값이 바뀌지 않는 다면 최적화를 위해 업데이트를 제어해줄 필요가 있다.

Array.jsx

...
...
    const count = useMemo(() => {
        return countActiveUsers(users);
    }, [users]);
...
...

첫 번째 파라미터엔 연산을 정의하는 함수를 넣어주면되고
두번째 파라미터엔 deps배열을 넣어주면된다. return 되는 값이 바뀌면 업데이트하고 바뀌지 않으면 그대로 사용하게 된다.

0개의 댓글