티스토리 뷰
< useEffect >
아래 코드는 state값이 변경될 때마다 useEffect가 렌더링 된다.
function App() {
const [value, setValue] = useState("");
useEffect(() => console.log("hello"));
return (
<>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</>
);
}
이유는 useState는 값이 바뀔때마다 즉 업데이트될 때마다 계속 렌더링이 일어난다.
렌더링이 일어난다는 말은 모든 함수가 다시 재실행 된다는 소리이다.
때문에 useEffect도 state 값이 변경 될때마다 리렌더링 되는 것이다.
그런데 useEffect는 특정한 값이 변경될 때만 일어나면 된다.
위코드에서는 처음 페이지를 열었을 때만 실행이 되길 바란다.
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [value, setValue] = useState("");
useEffect(() => console.log("hello"), []);
return (
<>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</>
);
}
export default App;
그럼 useEffect를 아래와 같이 2번째 값으로
내가 원하는 특정 행동의 값을 넣어주면 된다.
위 코드에서는 빈배열을 전달해 주었기 때문에 아무런 특정 값도 받지 않는다.
그냥 처음 실행되고 나서는 어떤 값을 받아도 리렌더링 되지 않을 수 있다는 것이다.
-- Dependency Array --
위에서 어떤 특정한 값이 변할때만 리렌더링이 되는 것을 Dependency Array, 의존성 배열이라고 할 수 있다.
의존성 배열을 잘 보여줄 수 있는 또다른 간단한 예시로,
button을 눌렀을때만 실행될 수 있도록 해보자.
const [value, setValue] = useState("");
const [clicked, setClicked] = useState(false);
useEffect(() => {
if (clicked) {
console.log("Button was clicked");
}
}, [clicked]);
return (
<>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
<button onClick={() => setClicked(true)}>Click Me</button>
</>
);
useEffect에 특정한 행동에 대한 값을 전달해 주어야 하기 때문에 clicked라는 state를 만들고
button에 state값을 전달해 useEffect에 전달해 주면
input에 값이 입력될 때마다가 아닌 입력이 끝나고 버튼을 클릭할때만 렌더링이 된다!.
그럼 button이 아니라 form 자체에 onSubmit이 될때만! 렌더링이 되려면 어떻게 해야 할까?
const [value, setValue] = useState("");
const [clicked, setClicked] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
setClicked(true);
};
useEffect(() => {
if (clicked) {
console.log("Button was clicked");
}
}, [clicked]);
return (
<>
<form onSubmit={handleSubmit}>
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
<button type="submit">Submit</button>
</form>
</>
);
이렇게 코드를 작성하면 버튼을 눌러도 엔터를 눌러서 값이 입력돼도
기본값인 false에서 ture로 변경되고, 상태가 변경되었기 때문에
useEffect이 렌더링 될 수 있다!
만약 clean up 즉 함수가 끝났다고 알려줄 수 있는 코드가 필요하다면
useEffect(() => {
console.log("hello")
return () => {
console.log("Buy~")
}
});
이렇게 사용할 수 있다!
마땅한 예시가 떠오르지 않아요..ㅎ
< useRef >
값을 저장하거나 DOM에 접근할 수 있게 해 줄 수 있는 Hooks이다.
쉽게 getElementById와 비슷한 역할을 해줄 수 있는 친구라고 생각하면 편할 것 같다.
useRef에는 current라는 속성을 가지고 있다.
function App() {
const idRef = useRef("");
useEffect(() => {
idRef.current.focus();
}, []);
return (
<>
<div>
아이디: <input ref={idRef} />
</div>
<div>
비밀번호: <input />
</div>
</>
);
}
useRef(초기값) 초기값을 꼭 넣어주고
사용하는 곳에서 current라는 속성을 이용해 useRef의 값을 변경해 줄 수 있다.
어떤 조건을 명시하고 싶을 수 있다.
그렇다면 항상 그 값에 접근을 해야 할 필요성을 알아야 한다.
만약 아이디의 값이 10개가 입력되면 비밀번호로 포커싱을 해줘야 하는 상황이라고 생각해 보자.
function App() {
const [id, setId] = useState("");
const idRef = useRef("");
const pwRef = useRef("");
useEffect(() => {
idRef.current.focus();
}, []);
useEffect(() => {
if (id.length >= 10) {
pwRef.current.focus();
}
}, [id]);
return (
<>
<div>
아이디:
<input
value={id}
onChange={(e) => setId(e.target.value)}
ref={idRef} />
</div>
<div>
비밀번호: <input ref={pwRef} />
</div>
</>
);
}
id에 접근이 가능해야 하고,
비밀번호에 접근하기 위해서는 새로운 useRef도 필요하다.
그리고 어떤 특정한 값이 변화될 때 실행되어야 하기 때문에 또 다른 useEffect도 필요하다.
새로 만든 useEffect에는 특정한 값이 변화될 때 실행되어야 하므로 특정 값을 2 번째 값을 전달해 주어야 한다.
📌 알고 넘어갑시다.
useEffect로 아이디의 길이를 확인하는 이유는
useState는 배치 업데이트로 일을 처리하게 된다.
이 말인즉슨 나는 10자리 일 때 비밀번호로 포커싱이 되어야 하는데
useState에서 조건을 주면 11자리가 입력되어야 10번째 값이 배치된다!
다음값이 입력되어야 직전값이 입력되어진다라고 생각하면 된다!
< 불필요한 렌더링을 줄여주는 Hooks >
memo(React.memo) : 컴포넌트 캐싱
export default React.memo(ComponentName);
컴포넌트를 내보내 주는 코드에서 React.mome(컴포넌트이름); 으로 작성해 주면 된다!
useCallback : 함수를 캐싱
const clear = () => {
setText("");
};
⬇️⬇️⬇️
const clear = useCallback(() => {
setText("");
}, []);
함수 부분을 useCallback()으로 감싸주면 된다. 그리고 2 번째 값으로 [ ] 안에 들어가는 값은
처음 useCallbak이 저장하고 있는 값을 어떤 특정한 값으로 변경하고 싶다면
예를 들어
useCallback은 초기값으로 빈 문자열을 가지고 있을 때
"A라는 내용을 setClean 하였습니다"라는 값을 출력하고 싶다면
A와 연결되어 있는 state 값을 넣어주어야 한다.
const [text,setText] = useState("");
const clean = useCallback(()=>{
console.log("{text}의 값을 모두 지웠습니다.")
setText("");
},[text]);
useMemo : 값을 캐싱(무거운 값을 다룰)
함수 영역이 겹쳐서 계속 리랜더링 되는 경우 useEffect를 사용해도 랜더링이 될 수 있다.
불변성으로 인해 새로운 주소 값을 참조하면서 값이 바뀌지 않아도 랜더링이 되는 것이다.
const [hungry, setHungry] = useState(false);
const person = useMemo(() => {
return {
name: "미주"
age: 5
hungry: hungry ? "배안고파" : "배고파"
} ;
},[hungry]);
그런 경우 useMemo를 사용해 더 견고하게 만들어 줄 수 있는데,
useMemo(()=> { return {}}, []) 로 함수 부분을 감싸주고 return문 안에 내용? 을 입력
그리고 [] 안에 어떤 값이 변경될 때만 렌더링이 되어야 하는지 값을 넣어주면 된다.
🔥주의사항 🔥
메모리를 많이 차지하기 때문에 너무 많이 사용하면 오히려 성능이 악화될 수 있으니
꼭 필요한 곳에만 사용해야한다.
'TIL' 카테고리의 다른 글
2024. 01. 28 날짜로만 디데이 구하기 (0) | 2024.01.29 |
---|---|
2024. 01. 26 Redux 알아보기 (3) | 2024.01.27 |
2024. 01. 24 Styled Component 설치 및 사용방법(yarn) (0) | 2024.01.24 |
2024. 01. 22 생각해보기 (0) | 2024.01.22 |
2024. 01 .21 css 스크롤 & git cache & README 작성해보기 (0) | 2024.01.21 |
- Total
- Today
- Yesterday
- axios instance 작성하기
- 영화별점만들기
- readme 이미지 추가 방법
- Warning: Each child in a list should have a unique "key" prop.
- styled component 사용방법
- Fetch와 Axios 의 장단점
- 유효성검사
- axiosinstance 사용 시 토큰 사용 법
- styled component 설치방법
- styled component 조건부 사용방법
- axios 설치하기
- 별점 색채우기
- Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>
- 에러모음집
- styled component GlobalStyle 사용방법
- Warning: A component is changing an uncontrolled input to be controlled.
- 별점만들기
- axios 사용하기
- readme 작성해야 하는 이유
- simple Icon 사용방법
- 영화 별점
- 유효성검사 css
- axios CRUD
- readme 작성 방법
- nextjs 토큰 만료처리하기
- git cache
- readme작성해보기
- readme 역할
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |