React 18의 새로운 기능

최신 버전의 React(버전 18)는 2022년 3월부터 공식적으로 사용할 수 있습니다. 많은 새로운 기능과 내부 변경 사항을 도입하여 프레임워크를 더욱 강력하게 만들었습니다. React는 계속해서 JavaScript 개발자가 선택하는 첫 번째이자 선호하는 프레임워크이며 회사에서 항상 많이 찾는 프레임워크입니다.

많은 새로운 기능이 React 18에 도입되었으며 오늘은 개발자가 프로젝트에서 가장 많이 사용할 가능성이 있는 인기 있는 기능 중 일부를 다룰 것입니다. 다음 내용을 다룰 것입니다.
  • 리액트 서스펜스
  • 새 루트 API
  • 새 useId 후크
  • The New useTransition hook

  • 리액트 서스펜스



    REST API를 사용하는 경우 데이터를 검색하는 두 가지 방법이 있습니다. 동기식 또는 비동기식으로 수행할 수 있습니다. 동기식 API 호출은 요청이 완료되거나 데이터를 반환하는 오류가 발생할 때까지 아무 것도 반환할 수 없기 때문에 차단 호출이라고 합니다. 이러한 유형의 API 호출은 애플리케이션을 잠그고 작업이 완료될 때까지 사용자가 아무 작업도 수행하지 못하게 합니다.

    반면에 비동기 API 호출은 이와 완전히 반대입니다. 비 차단이며 요청이 백그라운드에서 계속 처리되는 동안 응답이 즉시 반환됩니다. 애플리케이션은 응답성을 유지하고 어떤 일이 발생할 때까지 기다리지 않으므로 백그라운드에서 데이터를 검색하는 동안 애플리케이션을 계속 사용할 수 있습니다. 이것은 사용자에게 프런트엔드에서 훨씬 더 나은 경험을 제공합니다.

    본질적으로 React Suspense는 구성 요소가 API 또는 데이터 구조 내부의 데이터를 렌더링하기 전에 어떤 일이 발생할 때까지 기다리도록 하기 때문에 비동기식입니다. 구성 요소는 화면에 렌더링되기 전에 비동기 API 호출이 일부 데이터 가져오기를 완료할 때까지 기다려야 합니다. 이면에서 데이터가 로드되고 사용자에게 폴백 프리로더를 표시하여 프런트엔드에서 어떤 일이 발생하고 있음을 알 수 있습니다.

    반응 서스펜스 예



    이것은 React.lazy() API와 결합된 React Suspense를 사용하는 새로운 구문입니다.App.js
    // The new syntax for React 18 using React.lazy() to delay loading the component so that Suspense works properly.
    
    import { Suspense, lazy } from 'react';
    
    const Pokemon = lazy(() => {
        return import('./Pokemon');
    });
    
    const App = () => {
        return (
            <Suspense fallback={<h1>Loading pokemon...</h1>}>
                <Pokemon />
            </Suspense>
        );
    };
    
    export default App;
    

    Pokemon.js
    // The new syntax for React 18
    
    import React, { useEffect, useState } from 'react';
    
    const Pokemon = () => {
        useEffect(() => {
            const getPokemons = () => {
                const API = 'http://pokeapi.co/api/v2/pokemon?limit=500';
    
                fetch(API)
                    .then((response) => {
                        console.log(response);
    
                        return response.json();
                    })
    
                    .then((data) => {
                        console.log(data.results);
    
                        setData(data.results);
                    })
    
                    .catch((err) => {
                        console.log(err);
                    });
            };
    
            getPokemons();
        }, []);
    
        const [data, setData] = useState([]);
    
        return (
            <>
                {/* You don't need a ternary operator with a variable for loading anymore */}
    
                {data.map((pokemon) => (
                    <div key={pokemon.name}>
                        <h2>{pokemon.name}</h2>
                    </div>
                ))}
            </>
        );
    };
    
    export default Pokemon;
    


    삼항 연산자 예



    이것은 데이터가 로드 중인지 또는 로드되었는지 확인하는 변수 상태와 결합된 JavaScript 삼항 연산자를 사용하는 이전 구문입니다. 데이터가 아직 로드되지 않은 경우 프리로더를 표시하고 완료되면 데이터를 표시합니다.
    App.js
    // The old syntax
    
    import Pokemon from './Pokemon';
    
    const App = () => {
        return (
            <>
                <Pokemon />
            </>
        );
    };
    
    export default App;
    

    Pokemon.js
    // The old syntax
    
    import React, { useEffect, useState } from 'react';
    
    const Pokemon = () => {
        useEffect(() => {
            const getPokemons = () => {
                const API = 'http://pokeapi.co/api/v2/pokemon?limit=500';
    
                fetch(API)
                    .then((response) => {
                        console.log(response);
    
                        return response.json();
                    })
    
                    .then((data) => {
                        console.log(data.results);
    
                        setLoading(false);
    
                        setData(data.results);
                    })
    
                    .catch((err) => {
                        console.log(err);
                    });
            };
    
            getPokemons();
        }, []);
    
        const [data, setData] = useState([]);
    
        const [loading, setLoading] = useState(true);
    
        return (
            <>
                {/* The old syntax using ternary operators with a variable for loading */}
    
                {loading ? (
                    <h1>Loading pokemon...</h1>
                ) : (
                    <div>
                        {data.map((pokemon) => (
                            <div key={pokemon.name}>
                                <h2>{pokemon.name}</h2>
                            </div>
                        ))}
                    </div>
                )}
            </>
        );
    };
    
    export default Pokemon;
    


    새로운 루트 API



    React 18에는 새로운 기능과 개선 사항에 대한 액세스를 제공하는 루트 index.js 파일에 대한 새로운 구문이 있습니다. 이전 구문은 ReactDOM.render가 React 18에서 더 이상 지원되지 않기 때문에 콘솔에 빨간색 경고 메시지를 표시합니다. 새 구문을 사용하여 경고 메시지를 지웁니다.

    이제 대신 createRoot를 사용해야 하며 새 API로 전환할 때까지 앱은 React 17을 실행하는 것처럼 작동합니다. 새 루트 API에는 구문이 더 명확하고 명확하며 새 동시 렌더러가 활성화되어 이제 액세스할 수 있습니다. 이전 API가 할 수 없었던 동시 기능.

    새 구문




    import ReactDOM from 'react-dom/client';
    
    import App from './App';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    
    root.render(<App />);
    


    이전 구문




    import React from 'react';
    
    import ReactDOM from 'react-dom';
    
    import App from './App';
    
    ReactDOM.render(<App />, document.getElementById('root'));
    


    새로운 useId 후크



    React 18은 새로운 useId 후크로 DOM 요소를 생성할 때 ID를 생성하는 유용한 방법을 제공합니다. ID가 여러 개인 경우 "twitter"와 같은 접미사를 추가하여 고유하게 만들 수도 있습니다.

    보너스 팁: 예를 들어 htmlFor 태그를 추가하여 레이블을 클릭 가능하게 만들 수 있습니다.
    App.js
    import { useId } from 'react';
    
    const App = () => {
        const id = useId();
    
        return (
            <>
                <div>
                    <label htmlFor={`${id}-twitter`}>Do you have a Twitter?</label>
    
                    <input id={`${id}-twitter`} type="checkbox" name="twitter" />
                </div>
    
                <div>
                    <label>Do you have a Instagram?</label>
    
                    <input id={`${id}-instagram`} type="checkbox" name="instagram" />
                </div>
    
                <div>
                    <label>Do you have a YouTube?</label>
    
                    <input id={id} type="checkbox" name="youtube" />
                </div>
            </>
        );
    };
    
    export default App;
    


    새로운 useTransition 후크



    React 18에서는 새로운 useTransition 후크를 사용하여 데이터를 화면에 렌더링하기 전에 로드할 수 있습니다. 반환 값 isPending을 사용하면 각 로딩 전환에 대한 프리로더를 생성할 수 있습니다.

    이 맞춤형 캐러셀 슬라이더에서 실제로 작동하는 것을 볼 수 있습니다.
    App.js
    import { useState, useEffect, useTransition } from 'react';
    
    const App = () => {
        useEffect(() => {
            mountain().then((data) => {
                console.log(data);
    
                setLoading(false);
    
                setData(data);
            });
        }, []);
    
        let [data, setData] = useState([]);
    
        let [loading, setLoading] = useState(true);
    
        let [count, setCount] = useState(0);
    
        let [index, setIndex] = useState(0);
    
        let [isPending, startTransition] = useTransition();
    
        const showNext = () => {
            startTransition(() => {
                setCount(count + 1);
            });
    
            setIndex(count + 1);
    
            console.log('Count', count + 1);
        };
    
        const showPrevious = () => {
            startTransition(() => {
                setCount(count - 1);
            });
    
            setIndex(count - 1);
    
            console.log('Count', count - 1);
        };
    
        const mountain = (loaded) => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (loaded) {
                        reject(new Error('Failed to load data'));
                    } else {
                        resolve([
                            {
                                id: 0,
    
                                name: 'Mountain 1',
    
                                img: 'https://images.unsplash.com/photo-1570641963303-92ce4845ed4c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80',
                            },
    
                            {
                                id: 1,
    
                                name: 'Mountain 2',
    
                                img: 'https://images.unsplash.com/photo-1434394354979-a235cd36269d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2051&q=80',
                            },
    
                            {
                                id: 2,
    
                                name: 'Mountain 3',
    
                                img: 'https://images.unsplash.com/photo-1472791108553-c9405341e398?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2137&q=80',
                            },
                        ]);
                    }
                }, 2000);
            });
        };
    
        return (
            <>
                {loading ? (
                    <h1>Loading...</h1>
                ) : (
                    <div>
                        {isPending ? (
                            <div>
                                <h1>Loading the next image</h1>
                            </div>
                        ) : (
                            <div>
                                <h1>{data[index].name}</h1>
    
                                <img src={data[index].img} alt="Mountain" style={{ width: '100%', height: '300px', maxWidth: '500px' }} />
                            </div>
                        )}
                    </div>
                )}
    
                <button onClick={showPrevious} disabled={count === 0 ? true : false}>
                    Previous
                </button>
    
                <button onClick={showNext} disabled={count === 2 ? true : false}>
                    Next
                </button>
            </>
        );
    };
    
    export default App;
    


    마지막 생각들



    이것은 React 18 내부의 새로운 기능에 대한 간략한 소개였습니다. 모든 새로운 문서React v18.0를 보려면 공식 블로그를 살펴보십시오.

    좋은 웹페이지 즐겨찾기