리액트 18

김종원·2022년 7월 4일
0

[TIL (Today I Learned)]

목록 보기
25/45

리액트18 신기능

1. Automatic batching

리액트 18 이전 방식
1) state_1 변경
2) 재렌더링
3) state_2 변경
4) 재렌더링

리액트 18
1) state_1 변경
3) state_2 변경
4) 재렌더링
더 효율적으로 동작하도록 변경되었습니다.

2. startTransition

  • useTransition으로 느린 컴포넌트 성능향상 가능
import { useState } from "react";

const a = new Array(10000).fill(0);

function App() {
	const [name, setName] = useState('');
    
    return (
    	<div className="App">
        	<input onChange={(e) => {setName(e.target.value)}} />
            {
            	a.map( ()=>{
                	return <div>{name}<div>
                })
            }
        </div>
    );
}

input tag에 유저가 입력을 하면 name 변수에 저장됩니다.
setName(e.target.value)에 유저가 입력한 값이 변경되기 때문에 성능 저하가 일어납니다.

리액트 18

startTransition으로 setName(e.target.value)을 감싸주면 됩니다.
이렇게 하면 사용 전보다 성능이 향상됩니다.

import { useState, useTransition } from "react";

const a = new Array(10000).fill(0);

function App() {
	const [name, setName] = useState('');
    const [isPending, startTransition] = useTransition();
    
    return (
    	<div className="App">
        	<input onChange={(e) => {
            	startTransition( () => {
            		setName(e.target.value)
                });
            }} />
            {
            	a.map( ()=>{
                	return <div>{name}<div>
                })
            }
        </div>
    );
}

startTransition 동작원리

브라우저는 single-threaded이기 때문에 동시작업을 할 수 없는데 input tag에 값을 입력하면
브라우저는 '입력값'을 input tag에 보여주기, div tag 10000개 만들기를 해야합니다.
이것을 동시에 처리하려다 보니 성능 저하가 일어납니다.

startTransition을 사용하게 되면 startTransition 안에 있는 코드를 약간 늦게 처리해줍니다. -> 다른 작업을 먼저하고 코드시작을 뒤로 늦춰주는것!
이 것을 통해 성능향상을 도와준다

const [isPending, startTransition] = useTransition();에서
"isPending"은 startTransition가 처리중일때 true 값으로 변경됩니다.

그래서 이 값을 사용하면 이런식으로 사용할 수 있습니다.

import { useState, useTransition } from "react";

const a = new Array(10000).fill(0);

function App() {
	const [name, setName] = useState('');
    const [isPending, startTransition] = useTransition();
    
    return (
    	<div className="App">
        	<input onChange={(e) => {
            	startTransition( () => {
            		setName(e.target.value)
                });
            }} />
            {
            	isPending ? <div>로딩중</div> :
            	a.map( ()=>{
                	return <div>{name}<div>
                })
            }
        </div>
    );
}

3. useDeferredValue

useDeferredValue를 써도 느린 컴포넌트 성능을 향상 시킬 수 있습니다.

import { useState, useTransition, useDeferredValue } from "react";

const a = new Array(10000).fill(0);

function App() {
	const [name, setName] = useState('');
    const [isPending, startTransition] = useTransition();
    const stateDefer = useDeferredValue(name);
    
    return (
    	<div className="App">
        	<input onChange={(e) => {
            	startTransition( () => {
            		setName(e.target.value)
                });
            }} />
            {
            	isPending ? <div>로딩중</div> :
            	a.map( ()=>{
                	return <div>{stateDefer}<div>
                })
            }
        </div>
    );
}

const state = useDeferredValue(state);
useDeferredValue(state)에 넣은 state가 변동사항이 생기면 늦게 처리해줍니다.
이렇게 하면 name이라는 state가 변할때마다 늦게 처리해줍니다.

profile
발전하기위한 기록

0개의 댓글