나 림졍, 난관에 봉차크하다. 그거슨 바로 스딴다드.. 타임어따끄.
(아니 만들었던 과제를 왜 다시 1시간만에 만들어;)
강의도 듣고 정리도 하고 실습도 하고 이걸 언제 다 하라는건지..^^ 아오
까라면 까야죠 뭐.. 가보자고.
React (리액트) 강의 정리 - 숙련 ver. (이어서)
aㅏ. 정말 하기싫네.
useRef
useRef : 특정 값을 저장하기 위해 사용함. import 해서 사용 (얘도 React에서 제공하는 훅이라.)
특징 : 값 유지(리렌더링과 무관), 컴포넌트 리렌더링 시, 초기화되지 않는 변수 생성
==> 변수 유지 or DOM API(in JS) 사용없이 DOM 요소에 직접 접근할 때 사용
- 예시 (변경 전)
import "./App.css";
import { useRef } from "react";
function App() {
const ref = useRef("초기값");
console.log("ref", ref);
return (
<div>
<p>useRef에 대한 이야기에요.</p>
</div>
);
}
export default App;
+) ref의 값은 다음과 같다. (useState 처럼, 초기값 할당 가능)
ref ▶ { current : '초기값' }
- 변경 후 ( .current로 변경 가능 )
import "./App.css";
import { useRef } from "react";
function App() {
const ref = useRef("초기값");
console.log("ref 1", ref);
ref.current = "바꾼 값";
console.log("ref 1", ref);
return (
<div>
<p>useRef에 대한 이야기에요.</p>
</div>
);
}
export default App;
+) 변경 전후 차이비교
ref 1 ▶ { current : '초기값' }
ref 1 ▶ { current : '바꾼 값' }
∴ 이렇게 설정된 ref 값, 컴포넌트가 쭈우욱 렌더링 되어도 unmount 전까지는 값 유지함! (매우 중요)
사용 용도
1) 저장공간 (state와의 차이점)
- state처럼 값을 저장하는 역할 수행, but 차이점은 변화가 일어나면 리렌더링을 발생시키지 않는다는 것
- 값이 변경되면 컴포넌트를 다시 렌더링(state), useRef에 저장된 값은 리렌더링을 X, 렌더링 이후에도 유지
ex) 컴포넌트가 100번 렌더링되어도 useRef에 저장된 값은 계속 유지
→ ∴ 리렌더링이 필요하지 않은 데이터를 저장할 때 유용
정리하자면..
- state는 리렌더링이 필요한 값 다룰 때 사용
- useRef는 리렌더링이 불필요한 값 저장할 때 사용
2) DOM 접근
- 특정 DOM 요소에 접근 가능 - ex) 페이지가 로드되자마자 특정 input에 자동으로 포커스 조정
이때 useRef, HTML 요소에 연결, 해당 요소를 직접 조작할 수 있는 참조를 제공
useEffect와 함께 사용하여 DOM 요소가 마운트된 후 포커스 or 스타일 변경가능
import "./App.css";
function App() {
return (
<>
<div>
아이디 : <input type="text" />
</div>
<div>
비밀번호 : <input type="password" />
</div>
</>
);
}
export default App;
+) 추가 : < input /> 태그에 ref라는 속성 이용. 이걸 통해 우리는 해당 DOM 요소로 접근할 수 있음.
import { useEffect, useRef } from "react";
import "./App.css";
function App() {
const idRef = useRef("");
// 렌더링이 될 때
useEffect(() => {
idRef.current.focus();
}, []);
return (
<>
<div>
아이디 : <input type="text" ref={idRef} />
</div>
<div>
비밀번호 : <input type="password" />
</div>
</>
);
}
export default App;
[정리]
- 포커스 줄 때 DOM 요소에 대한 직접적 참조 필요 시, ref 사용
- ref 속성, 모든 HTML 요소에 사용 가능. ∴ input, div, span, button 등 다양한 HTML 태그에서 사용가능
- 포커스 주거나, 특정 값 가져오거나.. DOM 요소의 속성 수정 시 유용
useContext
useContext
- React의 Context API와 함께 사용하는 hook
- 컴포넌트 트리에서 여러 컴포넌트 간 데이터를 쉽게 공유 가능하도록 도와줌.
- 자식 컴포넌트, 반복적으로 props를 전달할 필요 없이 데이터 바로 사용할 수 있음. (prop drilling 이슈 해결)
Prop drilling
- 부모-> 자식 -> 그 자식 -> 그 자식의 자식 props, 깊이 전달 되면서 발생하는 현상
- cf. prop drilling의 문제점
1) 깊이가 너무 깊어지면 어떤 컴포넌트로부터 왔는지 파악이 어려워짐
2) 어떤 컴포넌트에서 오류가 발생할 경우 추적이 힘들어지니 대처가 늦어짐
이런 prop drilling 이슈를 해결하기 위해 등장한 것이 react context API,
useContext hook 으로 전역데이터를 쉽게 관리 할 수 있게됨.
Context API의 주요 구성 요소
- createContext: 새로운 Context 생성. 데이터를 공유할 수 있는 공간을 제공함.
- Provider: Context에서 데이터를 제공해주는 역할을 함.
Provider 사용해 하위 컴포넌트들에 데이터를 공급하며, value 속성으로 전달할 데이터를 지정. - Consumer or useContext: 하위 컴포넌트에서 Context의 데이터를 사용할 때 사용하는 방법 중 하나.
주로 useContext 훅을 사용하여 더 간단하게 Context 데이터를 사용
코드로 구현해보기
1) useContext 사용 안했을 때..
[ App.jsx ]
import "./App.css";
import GrandFather from "./components/GrandFather";
function App() {
return <GrandFather />;
}
export default App;
[ GrandFather.jsx ]
import React from "react";
import Father from "./Father";
function GrandFather() {
const houseName = "스파르타";
const pocketMoney = 10000;
return <Father houseName={houseName} pocketMoney={pocketMoney} />;
}
export default GrandFather;
[ Father.jsx ]
import React from "react";
import Child from "./Child";
function Father({ houseName, pocketMoney }) {
return <Child houseName={houseName} pocketMoney={pocketMoney} />;
}
export default Father;
[ Child.jsx ]
import React from "react";
function Child({ houseName, pocketMoney }) {
const stressedWord = {
color: "red",
fontWeight: "900",
};
return (
<div>
나는 이 집안의 막내에요.
<br />
할아버지가 우리 집 이름은 <span style={stressedWord}>{houseName}</span>
라고 하셨어요.
<br />
게다가 용돈도 <span style={stressedWord}>{pocketMoney}</span>원만큼이나
주셨답니다.
</div>
);
}
export default Child;
[결과]
GrandFather이 Child에게 houseName과 pocketMoney를 전달해주기 위해 Father 컴포넌트를 거칠 수 밖에 없고, 만약 이렇게 거쳐야할 컴포넌트가 10개, 100개 ... 그 이상 엄청 많다고 가정하면 코드가 너무 비효율적임.
그래서 useContext를 사용함!!!
2) useContext 사용 했을 때
이렇게 전역 데이터를 위한 파일 만들어주기
[ FaimilyContext.js ]
import { createContext } from "react";
// 여기서 null로 초기화를 시켜주고, 나중에 Provider로 값을 받을 때 다시 그 값 할당 받음.
export const FamilyContext = createContext(null);
[ GrandFather.jsx ]
import React from "react";
import Father from "./Father";
import { FamilyContext } from "../context/FamilyContext";
function GrandFather() {
const houseName = "스파르타";
const pocketMoney = 10000;
return (
<FamilyContext.Provider value={{ houseName, pocketMoney }}>
<Father />
</FamilyContext.Provider>
);
}
export default GrandFather;
[ Father.jsx ]
import React from "react";
import Child from "./Child";
function Father() {
return <Child />;
}
export default Father;
[ Child.jsx ]
import React, { useContext } from "react";
import { FamilyContext } from "../context/FamilyContext";
function Child({ houseName, pocketMoney }) {
const stressedWord = {
color: "red",
fontWeight: "900",
};
const data = useContext(FamilyContext);
console.log("data", data);
return (
<div>
나는 이 집안의 막내에요.
<br />
할아버지가 우리 집 이름은 <span style={stressedWord}>{data.houseName}</span>
라고 하셨어요.
<br />
게다가 용돈도 <span style={stressedWord}>{data.pocketMoney}</span>원만큼이나
주셨답니다.
</div>
);
}
export default Child;
[ 결론 ]
useContext, 중간 컴포넌트를 거치지 않고, 필요한 곳에서 useContext로 데이터를 바로 가져올 수 있음.
벗-뜨 Context = 전역데이터 이므로, Context 값 변경되면, 해당 Context를 참조하는 모든 컴포넌트 다시 리렌더링됨 (성능 떨어질 수도?)
→ React.memo로 최적화가능
마무리 - 으어ㅓ 살려주ㅅㅔ요.
힘들다.. 언제 발제 듣고
언제 라이브코딩하고 언제 다 하지..?
프로젝트 도대체 언제하지..? 살려주세요.
((동공지진))
KPT 회고
- Keep :
- Problem : 만성 피로 만성 두통 살려주세요.
- Try : ... 내일 일어날 수 있을ㄲr
'React TIL' 카테고리의 다른 글
[React] Day_35 데일리 정리 (0) | 2024.11.07 |
---|---|
[React] Day_34 데일리 정리 (1) | 2024.11.06 |
[React] Day_32 데일리 정리 (5) | 2024.11.04 |
[React] Day_31 개인 프로젝트 후기 (3) | 2024.11.01 |
[React] Day_30 개인 프로젝트 중간점검 (0) | 2024.10.31 |