[React] React hooks 정리 part.1 - useState, useEffect, useRef, useContext + Context API
매일 React hook에게 다져지는 내 자신이 안타까워
나는 오늘로서 hook을 잘게 다지기로 하였다. 뚜둔.
하지만 너무 길어서 최적화 부분은 Part.2로 넘겨야겠닫..ㅎ
🔗 useState
useState는 매우 중요하기 때문에, 별도로 정리해놓은 포스팅이 있으니 그곳으로 ㄱㄱ
🔗 useEffect
useEffect는 Lifecycle(생명주기)와 관련이 있고 생명주기를 이용해 특정 작업을 실행할 수 있도록 하는 hook이다.
useEffect의 실행 조건
- 마운트
- 컴포넌트가 페이지에 처음 렌더링 된 후 useEffect는 ‘무조건’ 실행된다.
- 업데이트
- useEffect의 dependency array의 state 값이 변경 될 때
- 부모가 리렌더링 될 때
- context가 바뀔 때
- 언마운트
- 컴포넌트가 페이지에서 사라질 때
기본문법
//렌더링 될 때마다 실행
useEffect(() => { 작업내용 });
//렌더링 될 때 딱 한 번만 실행
useEffect(() => { 작업내용 },[]);
//컴포넌트가 화면에 나타날 때(마운트) + dependency array의 값이 변경 될 때마다 실행
useEffect(() => { 작업내용 },[value]);
useEffect(() => {
});
예제
import { useEffect, useState } from "react";
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleChangeName = (e) => {
setName(e.target.value);
};
useEffect(() => {
console.log("렌더링🎨");
});
useEffect(() => {});
return (
<div className="App">
<div>
<button onClick={handleCountUpdate}>Update</button>
<p>count: {count}</p>
<div>
<input type="text" value={name} onChange={handleChangeName} />
<p>Name: {name}</p>
</div>
</div>
</div>
);
}
export default App;
이렇게 작성하면 화면에 컴포넌트가 마운트 될 때, 버튼을 클릭해서 count 값이 하나씩 변경 될 때, input text의 value 값을 입력하면서 name의 값이 변경 될 때에도 콘솔창에 ‘렌더링🎨’ 텍스트가 중복으로 출력 된다.
dependency array가 존재하지 않기 때문에 각 값이 변경될 때마다 화면이 재렌더링이 일어나기 때문에 콘솔창에 텍스트가 중복으로 출력되는 것이다.
만약 name의 값이 변경 될 땐 ‘name 렌더링🙋♀️’ 출력 되도록 하고 count의 값이 변경 될 땐 ‘count 렌더링💯’이 출력 되도록 하려면
import { useEffect, useState } from "react";
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleChangeName = (e) => {
setName(e.target.value);
};
// useEffect(() => {
// console.log("렌더링🎨");
// });
useEffect(() => {
console.log("name 렌더링🙋♀️");
}, [name]);
useEffect(() => {
console.log("count 렌더링💯");
}, [count]);
useEffect(() => {});
return (
<div className="App">
<div>
<button onClick={handleCountUpdate}>Update</button>
<p>count: {count}</p>
<div>
<input type="text" value={name} onChange={handleChangeName} />
<p>Name: {name}</p>
</div>
</div>
</div>
);
}
export default App;
이렇게 작성해주면 된다.
해석하자면,
// 렌더링 될 때마다 실행
useEffect(() => {
console.log("렌더링🎨");
});
// 마운트 + [name]가 변화 될 때마다 실행
useEffect(() => {
console.log("name 렌더링🙋♀️");
}, [name]);
// 마운트 + [count]가 변화 될 때마다 실행
useEffect(() => {
console.log("count 렌더링💯");
}, [count]);
만약 저렇게 재렌더링이 될때마다, 혹은 값이 변경될 때마다 실행되는 것이 아니라
화면이 렌더링 될 때 딱 한 번만 실행되도록 하려면 어떻게 해야할까?
// 마운팅 될 때 딱 한번만 실행
useEffect(() => {
console.log("마운팅🧗♀️");
}, []);
위와 같이 dependency array를 빈 배열로 두면 처음 마운팅이 될 때 딱 한 번 실행 된 뒤
state값이 변경되거나, 화면이 재렌더링이 되더라도 ‘마운팅🧗♀️’이라는 메시지는 두번 다시 출력되지 않는다.
import { useEffect, useState } from "react";
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleChangeName = (e) => {
setName(e.target.value);
};
// 렌더링 될 때마다 실행
useEffect(() => {
console.log("렌더링🎨");
});
// 마운트 + [name]가 변화 될 때마다 실행
useEffect(() => {
console.log("name 렌더링🙋♀️");
}, [name]);
// 마운드 + [count]가 변화 될 때마다 실행
useEffect(() => {
console.log("count 렌더링💯");
}, [count]);
// 마운팅 될 때 딱 한번만 실행
useEffect(() => {
console.log("마운팅🧗♀️");
}, []);
useEffect(() => {});
return (
<div className="App">
<div>
<button onClick={handleCountUpdate}>Update</button>
<p>count: {count}</p>
<div>
<input type="text" value={name} onChange={handleChangeName} />
<p>Name: {name}</p>
</div>
</div>
</div>
);
}
export default App;
useEffect의 Clean Up(언마운트)
기본문법
//언마운트, 업데이트 직전 마다 실행
useEffect(() => {
// ...실행내용
return () => { // 컴포넌트가 언마운트 될 때 실행 될 Clean-up 함수
// Clean-up 함수 실행 내용 (초기화)
};
});
//언마운트 될 때만 실행
useEffect(() => {
// ...실행내용
return () => { // 컴포넌트가 언마운트 될 때 실행 될 Clean-up 함수
// Clean-up 함수 실행 내용 (초기화)
};
}, []);
사용 이유
컴포넌트가 언마운트되거나, 업데이트 되기 직전에 작업을 수행하는 경우 useEffect 함수 내에서 Clean-up 함수를 반환해주면 되고
Event, setInterval, setTimeout 등 이펙트들을 정리해줌으로써, 메모리 누수를 막기 위해 사용한다.
정확한 이유는 아래 예제를 통해 알 수 있다.
//Timer.js
import { useEffect } from "react";
const Timer = (props) => {
useEffect(() => {
console.log("타이머가 호출 되었군요!");
const timer = setInterval(() => {
console.log("타이머가 실행중...");
}, 1000); // timer가 1초마다 실행
}, []);
return (
<>
<div>타이머를 시작합니다. 콘솔창을 보세요.</div>
</>
);
};
export default Timer;
//App.js
import { useEffect, useState } from "react";
import Timer from "./Timer";
function App() {
const [showTimer, setShowTimer] = useState(false);
return (
<div className="App">
<button
onClick={() => {
setShowTimer(!showTimer);
}}
>
Toggle Timer
</button>
{showTimer && <Timer />}
</div>
);
}
export default App;
이렇게 작성한 뒤 Toggle Timer 버튼을 클릭해보자.
그러면 화면에 타이머를 시작합니다~ … 텍스트가 렌더링 되면서
콘솔창에 ‘타이머가 실행중...’ 메시지가 1초마다 실행 될 것이다.
만약 Toggle Timer 버튼을 다시 한 번 더 클릭한다면
타이머를 시작합니다~ … 텍스트가 사라지면서 콘솔창에 ‘타이머가 실행중...’ 메시지가 출력 되는 것도 함께 멈추게 될까?
정답은 ‘아니다.’
버튼을 클릭해도 화면에 표시된 텍스트만 사라질 뿐,
콘솔창에는 ‘타이머가 실행중...’ 메시지가 여전히 1초마다 실행되는 것을 볼 수 있을 것이다.
만약 Timer 컴포넌트가 화면에서 사라질 때, 즉 언마운트 될 때 해당 값을 초기화하고자 한다면
Clean-up 함수를 이용해야 한다.
만약 Timer.js에서 Clean-up 함수를 적어준다면
//Timer.js
import { useEffect } from "react";
const Timer = (props) => {
useEffect(() => {
console.log("타이머가 호출 되었군요!");
const timer = setInterval(() => {
console.log("타이머가 실행중...");
}, 1000); // timer가 1초마다 실행
return () => {
clearInterval(timer);
console.log("타이머가 종료 되었군요.");
};
}, []);
return (
<>
<div>타이머를 시작합니다. 콘솔창을 보세요.</div>
</>
);
};
export default Timer;
위와 같이 수정해주면 된다.
이렇게 수정한 뒤 Toggle Timer 버튼을 두 번 클릭하면
타이머 또한 정상적으로 멈추고 그 값이 초기화 되는 것을 볼 수 있다.
🔗 useRef
기본문법
const ref = useRef(value)
// useRef를 부르면 ref 객체를 반환하고.
// 해당 객체 안에는 useRef안에 담아주었던 값은 current: vlaue로 저장된다.
// 반환값: {current: value}
// 또한 ref.current = "hello" 이런 식으로 값을 재 할당도 가능 하다.
useRef의 사용예제
- 저장공간으로 사용
- state 값을 변수로 사용할 땐 state값이 변화할 때마다 함수형 컴포넌트가 리렌더링(함수형 컴포넌트 재호출)이 일어나기 때문에 컴포넌트 내부 변수들이 초기화 된다.
- 하지만 ref를 사용하면 ref의 값을 아무리 변경해도 리렌더링 되지 않기 때문에, 따라서 컴포넌트 내부 변수들이 초기화 되지 않음.
- 그렇기 때문에 state가 변화되어 리렌더링이 일어나도, 값이 변화되면 안되는 변수들을 ref에 담아 보관한다.
- DOM 요소에 접근할 때 사용
- input focus 기능 등 DOM요소에 접근하고 제어할 때 사용
1. 저장공간으로 사용하는 Ref
⭐️ State와 Ref의 차이
import { useRef, useState } from "react";
function App() {
const [count, setCount] = useState(0);
//const countRef = useRef(0);
console.log("렌더링!");
const increaseCountState = () => {
setCount(count + 1);
};
return (
<div className="App">
<p>State: {count}</p>
<button onClick={increaseCountState}>State 올려</button>
</div>
);
}
export default App;
이와 같이 버튼을 클릭할 때마다, count state 값이 변하기 때문에 App component가 재렌더링이 일어나고 콘솔창에는 ‘렌더링!’ 메시지가 버튼 클릭 횟수 만큼 출력 되는 것을 확인할 수 있다.
import { useRef, useState } from "react";
function App() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
console.log("렌더링!");
const increaseCountState = () => {
setCount(count + 1);
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log(`Ref: ${countRef.current}`);
};
return (
<div className="App">
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseCountRef}>Ref 올려</button>
</div>
);
}
export default App;
코드를 위와 같이 추가해보자.
State 올려 버튼을 클릭하면 화면에 State의 값이 1씩 증가되는 것을 확인할 수 있으나,
Ref 올려 버튼을 아무리 클릭해도 화면에 Ref의 값은 0으로 변화되지 않는 것을 확인할 수 있다.
이에서 볼 수 있듯이 Ref의 값이 아무리 변화되더라도 리렌더링이 일어나지 않는다는 것을 알 수 있다.
State 올려 버튼과 Ref 올려 버튼을 각 순서대로 3번씩 클릭 후 다시 State 올려 버튼을 추가로 1회 클릭하면 그제서야 State: 4 / Ref: 3이 화면에 렌더링 되는 것을 볼 수 있을 것이다.
Ref의 값이 3으로 변경 된 뒤 State 올려 버튼을 클릭하면 화면이 재렌더링 되면서
컴포넌트 생에주기에 따라 그 값을 보존하는 성질의 Ref의 값은 그대로 유지 되기 때문에
count state의 값이 4로 재렌더링 되는 시점에 Ref: 3이 함께 렌더링 된 것이다.
여기서 볼 수 있는 Ref의 장점은
값이 자주 변화되는 변수를 State에 담는다면 리렌더링이 자주 일어나서 많은 자원을 낭비하게 될 것이나, Ref를 사용하여 변수에 담을 경우 값이 자주 바뀌더라도 리렌더링이 일어나지 않기 때문에 자원을 절약할 수 있다는 장점이 있다.
⭐️Var와 Ref의 차이
이제 기본 자료형 변수와 Ref의 차이에 대해서 알아보자.
import { useRef } from "react";
function App() {
const countRef = useRef(0);
let countVar = 0;
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log(`Ref: ${countRef.current}`);
};
const increaseCountVar = () => {
countVar += 1;
console.log(`Var: ${countVar}`);
};
return (
<div className="App">
<p>State: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={increaseCountRef}>Ref 올려</button>
<button onClick={increaseCountVar}>Var 올려</button>
</div>
);
}
export default App;
위와 같이 작성한 뒤 각 Ref 올려 / Var 올려 버튼을 클릭해보자.
두개의 버튼을 클릭하면 값이 변화하는 것을 콘솔창에서 확인할 수 있으나
변화된 값을 화면에 리렌더링 하지 않는 것을 확인할 수 있다.
이제 해당 값들이 변화될 때마다 리렌더링이 일어나도록 버튼을 하나 더 생성해보자.
import { useRef, useState } from "react";
function App() {
const [renderer, setRenderer] = useState(0);
const countRef = useRef(0);
let countVar = 0;
const dorendering = () => {
setRenderer(renderer + 1);
console.log("렌더 버튼을 클릭했어요.");
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log(`Ref: ${countRef.current}`);
};
const increaseCountVar = () => {
countVar += 1;
console.log(`Var: ${countVar}`);
};
return (
<div className="App">
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={dorendering}>렌더!</button>
<button onClick={increaseCountRef}>Ref 올려</button>
<button onClick={increaseCountVar}>Var 올려</button>
</div>
);
}
export default App;
렌더라는 버튼을 생성해준 뒤
각 Ref 올려 / Var 올려 버튼을 세 번씩 클릭하고 나서 렌더 버튼을 클릭해보자.
Ref의 값 3은 렌더링이 되었으나 Var의 값 3은 렌더링 되지 않고 0이 되었다.
그 이유는 무엇일까?
렌더 버튼을 클릭하면서 함수형 컴포넌트가 재호출이 되었고, 재호출 되면서 일반 변수의 값은 0으로 할당 되어있기 때문에 0으로 초기화가 되면서 0이 렌더링 된 것이다.
반면에 Ref 언마운트시 까지 그 값을 보존하는 성질이 있기 때문에 리렌더링시 값 3이 정상적으로 출력된 것이다.
저 상태에서 Var 올려 버튼을 클릭하게 된다면 콘솔창에는 Var: 1이 출력 되는 것을 알 수 있을 것이다.
import { useRef, useState } from "react";
function App() {
const [renderer, setRenderer] = useState(0);
const countRef = useRef(0);
let countVar = 0;
const dorendering = () => {
setRenderer(renderer + 1);
console.log("렌더 버튼을 클릭했어요.");
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log(`Ref: ${countRef.current}`);
};
const increaseCountVar = () => {
countVar += 1;
console.log(`Var: ${countVar}`);
};
const prinResults = () => {
console.log(`ref: ${countRef.current}, var: ${countVar}`);
};
return (
<div className="App">
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={dorendering}>렌더!</button>
<button onClick={increaseCountRef}>Ref 올려</button>
<button onClick={increaseCountVar}>Var 올려</button>
<button onClick={prinResults}>Ref Var 값 출력</button>
</div>
);
}
export default App;
위 코드의 버튼을 각각 눌러보며 렌더링 전 후로 Ref의 값과 Var의 값이 어떻게 유지되고 초기화되는지 살펴보도록 하자.
다른 예제
import { useEffect, useRef, useState } from "react";
function App() {
const [count, setCount] = useState(1);
const [renderCount, setRenderCount] = useState(1);
useEffect(() => {
console.log("렌더링!");
setRenderCount(renderCount + 1);
});
return (
<div className="App">
<p>Count: {count}</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
올려
</button>
</div>
);
}
export default App;
위와 같이 작성할 경우
useEffect 내부에서 컴포넌트가 마운트될 때 setRenderCount(renderCount + 1); 이 지속적으로 실행되게 되고 renderCount가 변화되므로써, 리렌더링이 일어나는 과정이 무한 반복 되므로 이와 같은 에러들이 발생할 것이다.
import { useEffect, useRef, useState } from "react";
function App() {
const [count, setCount] = useState(1);
const refRenderCount = useRef(1);
useEffect(() => {
refRenderCount.current = refRenderCount.current + 1;
console.log(`렌더링 수: ${refRenderCount.current}`);
});
return (
<div className="App">
<p>Count: {count}</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
올려
</button>
</div>
);
}
export default App;
코드를 위와 같이 수정한 뒤 올려 버튼을 클릭해보자.
useEffect에서 무한 에러를 발생시키지 않고 렌더링 수가 정상적으로 카운트 되는 것을 확인할 수 있을 것이다.
즉, useRef는 변화된 값은 감지해야 하지만, 그 변화가 화면을 렌더링 시키면 안되는 값을 다룰 때 사용해야 한다는 것을 알 수 있다.
2. DOM 요소에 접근할 때 사용하는 Ref
ref에 DOM 요소를 담아보자.
import { useEffect, useRef, useState } from "react";
function App() {
const inputRef = useRef();
useEffect(() => {
console.log(inputRef);
}, []);
return (
<div className="App">
<div>
<input ref={inputRef} type="text" placeholder="username" />
<button>로그인</button>
</div>
</div>
);
}
export default App;
inputRef에 input이 정상적으로 담긴 것을 확인할 수 있을 것이다.
import { useEffect, useRef, useState } from "react";
function App() {
const inputRef = useRef();
useEffect(() => {
console.log(inputRef);
inputRef.current.focus();
}, []);
const login = () => {
alert(`환영합니다. ${inputRef.current.value}님!`);
inputRef.current.focus();
};
return (
<div className="App">
<div>
<input ref={inputRef} type="text" placeholder="username" />
<button onClick={login}>로그인</button>
</div>
</div>
);
}
export default App;
위와 같이 작성하면
화면에 접속하자마자 input 폼에 포커싱이 되어있고,
e.target.value를 사용하지 않더라도 useRef만을 이용하여 input 폼의 값을 가져와 값을 입력 후 로그인 버튼 클릭 시 input의 값이 alert 창에 반영 된 것을 확인할 수 있으며.
alert창을 닫은 뒤에도 여전히 input 폼에 포커싱이 되어 있는 것을 확인할 수 있다.
🔗 useContext + Context API
props를 일일히 하위컴포넌트로 전달해주지 않더라도 필요한 위치에 해당 값을 전달해줄 수 있는 전역적 데이터 전달 방법
//App.js
import { useState } from "react";
import "./App.css";
import Page from "./components/Page";
function App() {
const [isDark, setIsDark] = useState(false);
return (
<div className="App">
<Page isDark={isDark} setIsDark={setIsDark} />
</div>
);
}
export default App;
//Page.js
import Content from "./Content";
import Footer from "./Footer";
import Header from "./Header";
const Page = ({ isDark, setIsDark }) => {
return (
<div className="page">
<Header isDark={isDark} />
<Content isDark={isDark} />
<Footer isDark={isDark} setIsDark={setIsDark} />
</div>
);
};
export default Page;
isDark state의 값을 Header / Content / Footer 컴포넌트에 사용하기 위해서 Page.js로 props를 통해 전달하고 있으나, 정작 Page 컴포넌트에서는 사용되지 않고 전달을 해주는 브릿지 역할만 하고 있는 것을 확인할 수 있다.
//ThemeContext.js
import { createContext } from "react";
export const ThemeContext = createContext(null);
ThemeContext.js 를 생성하고
import { useState } from "react";
import "./App.css";
import Page from "./components/Page";
import { ThemeContext } from "./context/ThemeContext";
function App() {
const [isDark, setIsDark] = useState(false);
return (
<ThemeContext.Provider value={{ isDark, setIsDark }}>
<div className="App">
<Page />
</div>
</ThemeContext.Provider>
);
}
export default App;
ThemeContext를 import한 뒤 Provider를 이용해 감싸준다.
이렇게 되면 모든 하위 컴포넌트들은 props를 사용하지 않아도
Provider value={{ isDark, setIsDark }} 로 넘겨준 값들에 접근할 수 있게 되는 것이다.
//Page.js
import { useContext } from "react";
import Content from "./Content";
import Footer from "./Footer";
import Header from "./Header";
import { ThemeContext } from "../context/ThemeContext";
const Page = () => {
const data = useContext(ThemeContext);
console.log(data);
return (
<div className="page">
{/* <Header isDark={isDark} />
<Content isDark={isDark} />
<Footer isDark={isDark} setIsDark={setIsDark} /> */}
</div>
);
};
export default Page;
useContext()를 활용하여 ThemeContext를 data 변수에 담아준 뒤 콘솔창에 출력해보자.
위와 같이 App.js에서 전달하였던 isDark / setIsDark의 값이 전달 된 것을 확인할 수 있다.
이제 Page.js에 있던 useContext를 모두 삭제해주자.
//Page.js
import Content from "./Content";
import Footer from "./Footer";
import Header from "./Header";
const Page = () => {
return (
<div className="page">
<Header />
<Content />
<Footer />
</div>
);
};
export default Page;
//Header.js
import { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
const Header = () => {
const { isDark } = useContext(ThemeContext);
return (
<header
className="header"
style={{
backgroundColor: isDark ? "black" : "lightgrey",
color: isDark ? "white" : "black",
}}
>
<h1>Welcome 홍길동</h1>
</header>
);
};
export default Header;
//Content.js
import { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
const Content = () => {
const { isDark } = useContext(ThemeContext);
return (
<div
className="content"
style={{
backgroundColor: isDark ? "black" : "white",
color: isDark ? "white" : "black",
}}
>
<p>홍길동님 좋은 하루 되세요.</p>
</div>
);
};
export default Content;
//Footer.js
import { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
const Footer = () => {
const { isDark, setIsDark } = useContext(ThemeContext);
const toggleTheme = () => {
setIsDark(!isDark);
};
return (
<footer
className="footer"
style={{
backgroundColor: isDark ? "black" : "lightgrey",
}}
>
<button className="button" onClick={toggleTheme}>
Dark Mode
</button>
</footer>
);
};
export default Footer;
위와 같이 Page.js에 props로 isDark / setIsDark 를 중간에 전달하지 않아도 isDark / setIsDark를 사용해야하는 컴포넌트들만이 useContext를 이용해 전달받았다.
만약 유저 정보를 useContext를 이용해 필요한 컴포넌트에만 보내고싶다면,
//UserContext.js
import { createContext } from "react";
export const UserContext = createContext(null);
//App.js
import { useState } from "react";
import "./App.css";
import Page from "./components/Page";
import { ThemeContext } from "./context/ThemeContext";
import { UserContext } from "./context/UserContext";
function App() {
const [isDark, setIsDark] = useState(false);
return (
<UserContext.Provider value={"사용자"}>
<ThemeContext.Provider value={{ isDark, setIsDark }}>
<div className="App">
<Page />
</div>
</ThemeContext.Provider>
</UserContext.Provider>
);
}
export default App;
//Header.js
import { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
import { UserContext } from "../context/UserContext";
const Header = () => {
const { isDark } = useContext(ThemeContext);
const user = useContext(UserContext);
return (
<header
className="header"
style={{
backgroundColor: isDark ? "black" : "lightgrey",
color: isDark ? "white" : "black",
}}
>
<h1>Welcome {user}!</h1>
</header>
);
};
export default Header;
위와 같이 UserContext 정보를 Header.js에 useContext를 이용해 user 변수에 담아 전달할 수 있다.
참고자료
유튜브 별코딩 리액트 훅
'Study > react.js' 카테고리의 다른 글
[React] 리액트 차트 라이브러리 Recharts.js 적용기(React chart library Recharts.js) (0) | 2023.06.27 |
---|---|
[React] React hooks 정리 part.2 useMemo(최적화) feat. React.memo (0) | 2023.02.28 |
[React] React Portal 기술을 이용하여 Modal을 만드는 방법(실습파일 하단 첨부) (0) | 2023.02.06 |
[React] React-query 정리 (0) | 2023.02.03 |
[React] 클래스형 vs 함수형 컴포넌트 차이 (class vs function component) (1) | 2022.12.08 |