728x90
반응형
SMALL
useCallback
useCallback 훅은 함수형 컴포넌트에서 함수를 메모이제이션 하는 데 사용됩니다. 여기서 메모이제이션이란, 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장하여 사용함으로써 동일한 계산의 반복 수행을 제거하여 성능 향상을 도모하는 기술을 말합니다.
문법
const cachedFn = useCallback(fn, dependencies)
예제
ex1)
import React, { useState } from "react";
const functionSet = new Set();
const App = () => {
const [count, setCount] = useState(0);
const [count2, setCount2] = useState(0);
const decrement = () => {
setCount(count - 1);
};
const increment = () => {
setCount(count + 1);
};
const otherIncrement = () => {
setCount2(count2 + 1);
};
functionSet.add(decrement);
functionSet.add(increment);
functionSet.add(otherIncrement);
console.log(functionSet);
return (
<div>
<h1>Count:{count}</h1>
<button onClick={decrement}>-</button>
<button onClick={increment}>+</button>
<hr />
<h1>Count2:{count2}</h1>
<button onClick={otherIncrement}>+</button>
</div>
);
};
export default App;
app.tsx
import { useCallback, useState } from "react";
import SubInput from "./components/SubInput";
const userInitailized = ["jack", "john", "jane", "Smith"];
const App = () => {
const [user, setUser] = useState(userInitailized);
const onChangeHandler = useCallback((text: string) => {
const filterUser = user.filter((item) => item.includes(text));
setUser(filterUser);
}, []);
const shuffle = () => {
setUser((user) => [...user].sort(() => Math.random() - 0.5));
};
return (
<>
<h1>App Component</h1>
<SubInput onChangeHandler={onChangeHandler} />
<button onClick={shuffle}>shuffle</button>
<ul>
{user.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</>
);
};
export default App;
subInput.tsx
import React from "react";
const SubInput = ({
onChangeHandler,
}: {
onChangeHandler: (text: string) => void;
}) => {
console.log("SubInput rendered");
return (
<>
<input
type="text"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
onChangeHandler(e.target.value);
}}
/>
</>
);
};
export default React.memo(SubInput);
useMemo
useMemo 훅은 값을 메모이제이션 하는 훅입니다. 여기서 메모이제이션이란, 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장하여 사용함으로써 동일한 계산의 반복 수행을 제거하여 성능 향상을 도모하는 기술을 말합니다.
문법
const cachedValue = useMemo(calculateValue, dependencies)
예제
ex1
import React, { useState } from "react";
const App = () => {
const [input, setInput] = useState("");
const [todo, setTodo] = useState<string[]>([]);
const todoLength = () => {
console.log("todoLength");
return todo.length;
};
const dummy = () => {
setTodo([...todo, input]);
};
return (
<div>
<h1>Todo Length : {todoLength()}</h1>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
/>
<button onClick={dummy}>Dummy Todo</button>
<pre>{JSON.stringify(todo)}</pre>
</div>
);
};
export default App;
app.tsx
import { useMemo, useState } from "react";
import { initialItems } from "./lib/utils";
const App = () => {
const [count, setCount] = useState(0);
// 불필요한 연산을 만들어준 것
// 3000만개의 배열 데이터를 렌더링 마다 재생성하고 있음
const [items] = useState(initialItems);
const selectItems = useMemo(() => items.find((item) => item.selected), []);
return (
<>
<h1>Count: {count}</h1>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>
증가
</button>
<p>{selectItems?.id}</p>
</>
);
};
export default App;
utils.ts
export const initialItems = new Array(29_999_999).fill(0).map((_, i) => {
return {
id: i,
selected: i === 29_999_998,
};
});
React.memo
React.memo 함수는 컴포넌트를 메모이제이션 할 때 사용합니다.
문법
const MemoizedComponent = React.memo(SomeComponent, arePropsEqual?)
예제
import { useCallback, useState } from "react";
import Header from "./components/Header";
import Footer from "./components/Footer";
const App = () => {
const [input, setInput] = useState("");
const [input2, setInput2] = useState("");
const changeHandler = useCallback(() => {
console.log("change");
}, []);
return (
<div>
<Header input={input} changeHandler={changeHandler} />
<Footer input={input2} changeHandler={changeHandler} />
<br />
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
/>
<br />
<input
type="text"
value={input2}
onChange={(e) => setInput2(e.target.value)}
/>
</div>
);
};
export default App;
useReducer
조금 더 복잡한 상태 관리를 할 때 사용하는 리액트 훅입니다. 넓은 범위에서 useState 훅과 비슷합니다.
문법
const [state, dispatch] = useReducer(reducer, initialState);
예제
ex1) non-reducer
import { useState } from "react";
import "./Counter.css";
const Counter = () => {
const [counter, setCounter] = useState(0);
return (
<div className="counter">
<h1>{counter}</h1>
<div>
<button onClick={() => setCounter((count) => (count -= 1))}>-</button>
<button onClick={() => setCounter((count) => (count += 1))}>+</button>
</div>
</div>
);
};
export default Counter;
.counter {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.counter h1 {
font-size: 50px;
}
.counter button {
width: 100px;
height: 50px;
background: none;
margin-right: 10px;
font-size: 30px;
}
.counter button:last-child {
margin-right: 0;
}
ex2) useReducer
import { useReducer } from "react";
import "./Counter.css";
const reducer = (state: number, action: { type: string }) => {
switch (action.type) {
case "increament":
return state + 1;
case "decreament":
return state - 1;
default:
return state;
}
};
const Counter = () => {
const [counter, dispatch] = useReducer(reducer, 0);
return (
<div className="counter">
<h1>{counter}</h1>
<div>
<button onClick={() => dispatch({ type: "decreament" })}>-</button>
<button onClick={() => dispatch({ type: "increament" })}>+</button>
</div>
</div>
);
};
export default Counter;
🔥 reduce 파일의 네이밍 규칙은 카멜 케이스를 따르는게 일반적입니다. ex) todoReducer.ts, createReducer.ts, authReducer.ts
[스나이퍼 팩토리 2기 과정]
본 학습 자료 및 코드는 수코딩님의 자료를 이용하였습니다. [수코딩(https://www.sucoding.kr)] 출처
728x90
반응형
LIST
'프론트엔드(Web) > React' 카테고리의 다른 글
리액트 데이터 통신 - 데이터 통신, Suspense와 ErrorBoundary, tanstack query (3) | 2024.08.28 |
---|---|
리액트 컨텍스트 - useContext, zustand (0) | 2024.08.28 |
리액트 훅 리액트 18 + - useId,동시성 모드 훅(useTransition,useDefferedValue,useTransition vs useDeferredValue) (0) | 2024.08.27 |
리액트 훅 기본 - (useState(),useRef(),useEffect(),useLayoutEffect() (1) | 2024.08.27 |
리액트 - 컴포넌트 기본문법(컴포넌트 생성, props, children, 조건부 및 반복 , 이미지 렌더링) (0) | 2024.08.25 |