React 개발자 도구 & lazy import 

개발자 도구

https://chromewebstore.google.com/ - react delveloper tools 검색 - 다운로드 

* react로 만들어진 페이지만 확인 가능

F12 - Components = Element보다 좀더 편하게 확인 가능

 

F12 - Profiler = 성능저하되는 컴포넌트 범인 찾기

 

lazy import

Single Page Application 특징 : js파일 하나에 모든 코드를 다 쑤셔 넣는다. (사이즈가 크다)

따라서, 해당 페이지를 로딩할 때 필요하지 않는 import부분이 있으면, 

그 부분은 lazy import()로 묶어준다

 

로딩 중일 때, 흰색 화면이 뜨기 때문에 그것을 방지하기 위해 

Suspense를 import해주고, lazy import한 컴포넌트 부분을 <Suspense>로 감싸준다

import { Container, Nav, Navbar } from 'react-bootstrap';
import './App.css';
import bg from './img/bg2.jpg';
import { createContext, lazy, Suspense, useEffect, useState } from 'react';
import data from './data.js';
import { Routes, Route, Link, useNavigate, Outlet} from 'react-router-dom'
import axios from 'axios'
import { useQuery } from 'react-query';

//import Detail from './routes/Detail.js'
// import Cart from './routes/Cart.js'

const Detail = lazy(() => import('./routes/Detail.js'));
const Cart = lazy(() => import('./routes/Cart.js'));


export let Context1 = createContext()

function App() {

  let obj = {name : 'kim'}

  let [shoes, setShoes] = useState(data)
  let [재고] = useState([10, 11, 12])
  
  let navigate = useNavigate();

  useEffect(() => {
    localStorage.setItem('watched', JSON.stringify([]))

  }, [])

  let result = useQuery('작명', () => {
    return axios.get('https://codingapple1.github.io/userdata.json').then((a) => {
      console.log('요청됨')
      return a.data;
    })
  })

  return (
    <div className="App">
      
      <Navbar bg="light" data-bs-theme="light">
        <Container>
          <Navbar.Brand href="#home">ShopShop</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link onClick={() => { navigate('/')}}>Home</Nav.Link>
            <Nav.Link onClick={() => { navigate('/cart') }}>cart</Nav.Link>
          </Nav>
          <Nav className='ms-auto'>
            {result.isLoading && '로딩중'}
            {result.error &&'에러남'}
            {result.data && result.data.name}
          </Nav>

        </Container>
      </Navbar>
      <Suspense fallback={<div>로딩중임</div>}>
      <Routes>
        <Route path='/' element={
          <>
          <div className='main-bg' style={{backgroundImage:'url(' + bg + ')' }}></div>
            <div className='container'>
              <div className='row'>
                {
                  shoes.map(function(a, i){
                    return(
                      <Card shoes = {shoes[i]} i = {i}></Card>
                    )
                  })
                }
              </div>
            </div>
            <button onClick={() => {
              axios.get('https://codingapple1.github.io/shop/data2.json')
              .then((data) => {
                console.log(data.data);
                let copy = [...shoes, ...data.data];
                setShoes(copy)
              })
              .catch(() => {
                console.log('실패함')
              })

            }}>더보기</button>
          </>
        } />
        <Route path='/detail/:id' element={
          <Context1.Provider value={{재고}}>
            
              <Detail shoes={shoes}/>
            
          </Context1.Provider >
        } />
        <Route path="/cart" element={<Cart></Cart>}></Route>
      </Routes>
      </Suspense>
      
    </div>
  );
}

function Card(props){
  let navigate = useNavigate();
  return(
    <div className='col-md-4'>
      <img onClick={() => {navigate('detail/' + (props.i))}} src={"https://codingapple1.github.io/shop/shoes" + (props.i+1) + ".jpg"} width="80%"></img>
      <h5>{props.shoes.title}</h5>
      <p>{props.shoes.price}</p>
    </div>
  )
}

export default App;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

React memo & useMemo

자식 컴포넌트 재렌더링 막기

자식 컴포넌트 무거울 경우 계속 재렌더링 할 경우 속도가 저하될 수 있으므로, 

재 렌더링 필요없는 경우면, memo(import 해줘야함)로 해당 컴포넌트를 감싸준다

 

* memo 원리 : memo로 된 함수의 props가 변할 때에는 재렌더링 된다

 

useMemo(함수) : 해당하는 페이지가 처음 로드 될때만 실행하고, 나머지는 실행하지 않는다

하지만 useEffect처럼 , [state] 를 통해 state가 변경될때도 실행 가능

import { Table } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { increase, changeName} from "./../store/userSlice";
import { addCount } from "./../store.js";
import { memo, useMemo, useState } from "react";

function 함수(){
    return 반복문 10억번;
}

let Child = memo( function(){
    console.log("재렌더링됨")
    return <div>자식임</div>
})

function Cart(){

    let result = useMemo(() => {return 함수()}, [state])

    let state = useSelector((state) => { return state })
    let dispatch = useDispatch()
    let [count, setCount] = useState(0)

    return(
        <div>
            <Child count={count}></Child>
            <button onClick={() => {setCount(count+1)}}>+</button>
            <h6>{state.user.name} {state.user.age}의 장바구니</h6>
            <button onClick={() => {dispatch(increase(10))}}>버튼</button>
            <Table>
                <thead>
                    <tr>
                        <th>#</th>
                        <th>상품명</th>
                        <th>수량</th>
                        <th>변경하기</th>
                    </tr>
                </thead>
                <tbody>
                    {
                        state.cart.map(function(a, i){
                            return(
                                <tr key={i}>
                                    <td>{a.id}</td>
                                    <td>{a.name}</td>
                                    <td>{a.count}</td>
                                    <td>
                                        <button onClick={() => {
                                            dispatch(addCount(a.id))
                                        }}>+</button>
                                    </td>
                                </tr>
                            )
                        })
                    }
                </tbody>
            </Table> 
        </div>
    )
}

export default Cart;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

React useTransition & useDeferredValue

useTransition

계산이 많아서 성능이 저하될 때, 해당하는 함수에 useTransition을 사용

동작 원리 : 코드 시작을 뒤로 늦춰서, 한꺼번에 코드를 처리할 때의 성능저하를 막아줌

사용 방법 : useTransition을 import 한다

 

계산이 복잡한 부분에 startTransition을 감싸준다

 

계산중(로딩중)일 때 true를 반환한다

 

useDeferredValue

useTransition과 마찬가지로 느린 컴포넌트 성능을 향상시켜줌

useDeferredValue(state명) : 복잡한 state가 변할때 성능 향상

+ Recent posts