컴포넌트 최적화에 사용
부하가 생기는 함수를 반복해서 작업할 때 기억해두었다가 사용하는 기법
import {useState, useMemo} from 'react'
function 부하(){
let s = 0
for (let i = 0; i < 1000000000; i++) {
s += i
}
return s
}
function App() {
const [count, setCount] = useState(0);
const reulst = useMemo(() => {
return 부하();
}, [])
const handleCountUp = (e) => {
setCount(count + 1);
console.log(count);
}
return (
<div>
{/* 해결하기 : 부하가 걸리는 작업을 저장한다. */}
<h1>계산 결과 : {result}</h1>
<div>{count}</div>
<button onClick={handleCountUp}>up!</button>
</div>
)
}
주의 : 모든 결과를 다 저장하면 메모리 낭비가 발생
최적화할 함수와 함수가 의존하게 될 값을 useMemo에게 전달
useMemo는 렌더링중 실행되어 의존하는 값이 변경되었는지 체크하여 변경된 경우에만 값을 다시 계산한다.
useMemo(실행될 것, [값])
일때 렌더링 전에 실행
되어 이전에 기억해둔 값을 반환 (렌더링 전에 저장된 것을 전송)
리렌더링을 막을 수 있다.
useEffect
는 렌더링 후
에 일어난다. (업데이트 된 경우를 감지)
상태를 이용한 관리에 사용
보통 컴포넌트에게 데이터를 props를 통해 넘겨준다
하지만 프로젝트가 커지는 경우 props가 계속 의미없이 전달되는 경우들이 발생한다.
=> context를 사용하여 props 사용하지 않고 데이터를 전달한다.
바로 n번째 자손에게 직접 데이터를 전달한다.
createContext로 context 생성
import {createContext} from 'react'
const Value = createContext({price:1000})
function Three() {
// 바로 Three로 전달 (props drilling을 하지 않고)
return (
<Value.Consumer>
{(value) => (<p>{value.price}</p>)}
</Value.Consumer>
)
}
function Two(){
return (
<div>
Two
<Three/>
</div>
)
}
function One(){
return (
<div>
One
<Two/>
</div>
)
}
export default function App() {
return (
<div>
<One/>
</div>
)
}
Consumer라는 컴포넌트를 통해 value 값을 가져옴
import {createContext} from 'react'
const Value = createContext({price:1000})
function Three() {
// 바로 Three로 전달 (props drilling을 하지 않고)
return (
<Value.Consumer>
{(value) => (<p>{value.price}</p>)}
</Value.Consumer>
)
}
function Two(){
return (
<div>
Two
{/* 값 변경해주기 */}
<Value.Provider value={{price:3000}}>
<Three/>
</Value.Provider>
</div>
)
}
function One(){
return (
<div>
One
<Two/>
</div>
)
}
export default function App() {
return (
<div>
<One/>
</div>
)
}
.Provider
로 감싸서 값을 전달하면 consumer로 전달되는 value의 값이 바뀜
value를 꼭
넣어서 Provider로 값을 전달해야 오류가 나지 않는다.
Context.consumer
방식으로 전달 => Hooks의 useContext
를 사용해서 더 편하게 값을 전달
import {useContext, createContext} from 'react'
const UserInfo = createContext({
name: 'lee',
id : 'licat',
email: 'licat@licat.com'
})
function One() {
const {name, id, email} = useContext(UserInfo);
return (
<div>
<p>{name}</p>
<p>{id}</p>
<p>{email}</p>
</div>
)
}
export default function App() {
return (
<div>
<One/>
</div>
)
}
useContext는 함수형 컴포넌트에서만 사용이 가능
useState를 사용해서 state를 초기화하는 과정을 게으르게
실행하도록 하는 것
함수 자체를 값으로 넘겨서 리액트가 그 함수를 실행하도록 만들기!
import React, {useEffect, useState} from 'react';
function getName() {
console.log('오래 기다리는 작업');
return '잉잉';
}
function App() {
// const [name, setName] = useState(getName());
// console.log가 한번만 찍힌다. 함수 자체를 넘기는 경우
const [name, setName] = useState(getName);
const [num, setNum] = useState(0);
return (
<>
<div>안녕하세요 {name}! 현재 숫자는 {num}입니다.!!</div>
<button onClick={() => setNum(p => p + 1)}>{num}</button>
</>
)
}
export default App;
useState(getName) -> 최초 초기화 진행에서 getName을 실행
이후 리렌더링에서 초기화가 진행되지 않기 때문에 getName 실행을 생략
초기값 계산에 비효율적인 부분을 최적화하기 위해 사용
반복되는 Hook을 마음대로 분리하고 재사용하기
import {useState} from 'react'
function use000(initState) {
const [value, setValue] = useState(initState);
function onChange(e) {
setValue(e.target.value);
}
return [value, onChange];
}
export default use000;
import React from 'react'
import use000 from '../Hook/use000';
function InputComponent() {
const [value, onChange] = use000('');
return (
<>
<input type="text" onChange={onChange}/>
<div>
{value}
</div>
</>
)
}
export default InputComponent;
value
와 상태를 조작하는 onChange
함수를 넘겨준다.