Recent Posts
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
관리 메뉴

개발자 박가나

[241105 TIL] 본캠프 25일차 본문

내일배움캠프

[241105 TIL] 본캠프 25일차

gnchoco97 2024. 11. 5. 17:30

  📌 오늘의 TIL
  • [React 숙련] 강의

 

 

 [React 숙련] 강의 

React.memo

컴포넌트를 memoization하는 방법이다.

 

부모 컴포넌트가 리렌더링되면 자식 컴포넌트는 변경된 부분이 없음에도 불구하고 불필요하게 리렌더링 되는데, React.memo를 이용해서 이를 방지할 수 있다.

 

  • 부모 컴포넌트
import { useState } from 'react';
import Box from './Box';

export default function App() {
    const [count, setCount] = useState(0);

    const handlePlus = () => setCount(count + 1);

    const handleMinus = () => setCount(count - 1);

    return (
        <>
            <p>현재 카운트 : {count}</p>
            <button onClick={handlePlus}>+</button>
            <button onClick={handleMinus}>-</button>
            <Box />
        </>
    );
}

 

  • 자식 컴포넌트
function Box() {
	return <div>Box</div>;
}

export default React.memo(Box);

 

useCallback

함수를 memoization하는 방법이다.

const [count, setCount] = useState(0);

const handleInitCount = useCallback(() => {
    setCount(0);
}, [count]);

 

useMemo

특정 값을 momoization하는 방법이다.

 

어떠한 값을 계산하는 로직이 엄청 복잡할 경우 리렌더링이 발생할 때마다 해당 로직을 수행하게 되면서 성능적으로 문제가 될 수 있는데, useMemo를 이용해서 이를 방지할 수 있다.

const heavyWork = () => {
    for (let i = 0; i < 1000000000; i++) {}

    return 100;
};

const value = useMemo(() => heavyWork(), []);

 

Redux

전역 상태 라이브러리이다.

 

Context API를 사용하는 방법도 있지만 이는 복잡하지 않은 상태 관리에 적합하다.

 

성능 최적화, 상태 로직의 중앙화 등의 이유로 대규모 어플리케이션에서는 Redux를 사용하는 것이 적합하다.

/* redux/config/configStore.js */

import { createStore, combineReducers } from 'redux';
import counter from '../modules/counter';

const rootReducer = combineReducers({
	counter
});

const store = createStore(rootReducer);

export default store;
/* main.jsx */

import store from './redux/config/configStore';
import { Provider } from 'react-redux';

createRoot(document.getElementById('root')).render(
    <StrictMode>
        <Provider store={store}>
        	<App />
        </Provider>
    </StrictMode>
);
/* redux/modules/counter.js */

const initialState = {
	number: 0
};

const PLUS_NUMBER = 'PLUS_NUMBER';
const MINUS_NUMBER = 'MINUS_NUMBER';

export const plusNumber = (payload) => {
      return { type: PLUS_ONE, payload };
};

export const minusNumber = (payload) => {
	return { type: MINUS_ONE, payload };
};

const counter = (state = initialState, action) => {
    switch (action.type) {
    	case PLUS_NUMBER:
        	return { number: state.number + action.payload };
        case MINUS_NUMBER:
        	return { number: state.number - action.payload };
        default:
        	return state;
    }
};

export default counter;
/* App.jsx */

import { useDispatch } from 'react-redux';
import { minusNumber, plusNumber } from './redux/modules/counter';

export default function App() {
    const dispatch = useDispatch();
    const counterReducer = useSelector((state) => state.counter);
    
    const [number, setNumber] = useState(0);

    return (
        <div>
            {countetReducer.number}
            <input type="number" onChange={(e) => setNumber(e.target.value)} />
            <button onClick={() => dispatch(plusNumber(number))}>더하기</button>
            <button onClick={() => dispatch(minusNumber(number))}>빼기</button>
        </div>
    );
};

 

RTK (Redux Toolkit)

Redux를 개량한 것이다.

 

코드는 더 적게, Redux는 더 편하게 사용하기 위한 기능들을 흡수한 결과물이다.

성능 최적화, 상태 로직의 중앙화 등의 이유로 대규모 어플리케이션에서는 Redux를 사용하는 것이 적합하다.

/* redux/config/configStore.js */

import { configureStore } from '@reduxjs/toolkit';
import counter from '../slices/counterSlice';

const store = configureStore({
    reducer: {
    	counter
    },
});

export default store;
/* main.jsx */

import store from './redux/config/configStore';
import { Provider } from 'react-redux';

createRoot(document.getElementById('root')).render(
    <StrictMode>
        <Provider store={store}>
        	<App />
        </Provider>
    </StrictMode>
);
/* redux/slices/counterSlice.js */

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
	number: 0,
};

const counterSlice = createSlice({
    name: 'counter',
    initialState,
    reducers: {
        plusNumber: (state, action) => {
        	state.number = state.number + action.payload;
        },
        minusNumber: (state, action) => {
        	state.number = state.number - action.payload;
        },
    },
});

export const { plusNumber, minusNumber } = counterSlice.actions;
export default counterSlice.reducer;
/* App.jsx */

import { useDispatch } from 'react-redux';
import { minusNumber, plusNumber } from './redux/modules/counter';

export default function App() {
    const dispatch = useDispatch();
    const counterReducer = useSelector((state) => state.counter);
    
    const [number, setNumber] = useState(0);

    return (
        <div>
            {countetReducer.number}
            <input type="number" onChange={(e) => setNumber(e.target.value)} />
            <button onClick={() => dispatch(plusNumber(number))}>더하기</button>
            <button onClick={() => dispatch(minusNumber(number))}>빼기</button>
        </div>
    );
};

 

Supabase

PostgreSQL을 기반으로 하는 BaaS 플랫폼이다.

/* supabaseClient.js */

import { createClient } from '@supabase/supabase-js';

const SUPABASE_PROJECT_URL = '...';
const SUPABASE_ANON_KEY = '...';

const supabase = createClient(SUPABASE_PROJECT_URL, SUPABASE_ANON_KEY);

export default supabase;
supabase.from('SPARTA_PRACTICE').select('*');

supabase.from('SPARTA_PRACTICE').insert({ name, age, address });

supabase.from('SPARTA_PRACTICE').update({ address }).eq('id', targetId);

supabase.from('SPARTA_PRACTICE').delete().eq('id', targetId);