728x90
리액트 공식문서 학습기록
https://react.dev/learn
Removing Effect Dependencies
종속성은 코드와 일치해야함
Effect는 반응값에 '반응’함. 그래서 linter는 그게 종속성에 있는지 확인함. 고로 linter가 시키는대로 하셈.
종속성을 제거하고 싶으면
[] 빈배열 던지셈
종속성을 변경하려면 코드를 고치셈
- Effect의 코드를 변경하거나 반응값이 선언되는 방식을 변경
- linter가 시키는 대로 종속성 조정
- 맘에 안 들면 1번으로 돌아가서 코드 변경
불필요한 의존성 제거
- 코드를 이벤트 핸들러로 이동해야하는지 -> 꼭 Effect여야하는지 여부
- Effect가 관련없는 일을 하고 있는가? -> 별도 통신을 한다던지
- 다음 상태를 계산하기 위해 일부 상태를 읽고있는지 -> 업데이트 기능을 전달하셈(🤔 잘 모르겠고)
변경 사항에 '반응’하지 않고 값을 읽고 싶을때
- 반응하면 안되는 부분을 Effect에서 추출하자
- props의 경우 useEffectEvent로 래핑하자
function ChatRoom({ roomId, onReceiveMessage }) {
const [messages, setMessages] = useState([]);
const onMessage = useEffectEvent(receivedMessage => {
onReceiveMessage(receivedMessage);
});
useEffect(() => {
const connection = createConnection();
connection.connect();
connection.on('message', (receivedMessage) => {
onMessage(receivedMessage);
});
return () => connection.disconnect();
}, [roomId]); // ✅ All dependencies declared
// ...
일부 반응값이 의도치 않게 변경될때
- 종속성
- 상수(값, 함수)를 컴포넌트 외부로 이동
- 내부에 객체를 생성하여 사용 -> 외부 편집 시 다시 동작하지 않음.
const serverUrl = 'https://localhost:1234';
function ChatRoom({ roomId }) {
const [message, setMessage] = useState('');
useEffect(() => {
const options = {
serverUrl: serverUrl,
roomId: roomId
};
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [roomId]); // ✅ All dependencies declared
// ...
과제 1
재렌더링 막기
👉 setter로 상태값을 변경하지말고 updater 함수 사용
import { useState, useEffect } from 'react';
export default function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('✅ Creating an interval');
const id = setInterval(() => {
console.log('⏰ Interval tick');
setCount(c => c + 1);
}, 1000);
return () => {
console.log('❌ Clearing an interval');
clearInterval(id);
};
}, []);
return <h1>Counter: {count}</h1>
}
과제 2
duration 변경시 재렌더링 막기
👉 useEffectEvent를 쓰자
import { useState, useEffect, useRef } from 'react';
import { FadeInAnimation } from './animation.js';
import { experimental_useEffectEvent as useEffectEvent } from 'react';
function Welcome({ duration }) {
const ref = useRef(null);
const onAppear = useEffectEvent(animation => {
animation.start(duration);
});
useEffect(() => {
const animation = new FadeInAnimation(ref.current);
onAppear(animation);
return () => {
animation.stop();
};
}, []);
return (
<h1
ref={ref}
style={{
opacity: 0,
color: 'white',
padding: 50,
textAlign: 'center',
fontSize: 50,
backgroundImage: 'radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%)'
}}
>
Welcome
</h1>
);
}
export default function App() {
const [duration, setDuration] = useState(1000);
const [show, setShow] = useState(false);
return (
<>
<label>
<input
type="range"
min="100"
max="3000"
value={duration}
onChange={e => setDuration(Number(e.target.value))}
/>
<br />
Fade in duration: {duration} ms
</label>
<button onClick={() => setShow(!show)}>
{show ? 'Remove' : 'Show'}
</button>
<hr />
{show && <Welcome duration={duration} />}
</>
);
}
과제 3
채팅 재접속 막기
👉 종속성을 객체로 전달하지 말고 따로따로 전달해라
import { useEffect } from 'react';
import { createConnection } from './chat.js';
export default function ChatRoom({ options }) {
const { roomId, serverUrl } = options;
useEffect(() => {
const connection = createConnection({
roomId: roomId,
serverUrl: serverUrl
});
connection.connect();
return () => connection.disconnect();
}, [roomId, serverUrl]);
return <h1>Welcome to the {options.roomId} room!</h1>;
}
과제 4
채팅 재접속 막기
👉 종속성을 똑바로
import { useState, useEffect } from 'react';
import { experimental_useEffectEvent as useEffectEvent } from 'react';
import {
createEncryptedConnection,
createUnencryptedConnection,
} from './chat.js';
export default function ChatRoom({ roomId, isEncrypted, onMessage }) {
const onReceiveMessage = useEffectEvent(onMessage);
useEffect(() => {
function createConnection() {
const options = {
serverUrl: 'https://localhost:1234',
roomId: roomId
};
if (isEncrypted) {
return createEncryptedConnection(options);
} else {
return createUnencryptedConnection(options);
}
}
const connection = createConnection();
connection.on('message', (msg) => onReceiveMessage(msg));
connection.connect();
return () => connection.disconnect();
}, [roomId, isEncrypted]);
return <h1>Welcome to the {roomId} room!</h1>;
}
'공부공부 > React' 카테고리의 다른 글
[react 공식문서] 30 Reusing Logic with Custom Hooks (0) | 2024.02.14 |
---|---|
[react 공식문서] 28 Separating Events from Effects (0) | 2024.02.14 |
[react 공식문서] 27 Lifecycle of Reactive Effects (0) | 2024.02.14 |
[react 공식문서] 26 You Might Not Need an Effect (0) | 2024.02.14 |
[react 공식문서] 25 Synchronizing with Effects (0) | 2024.02.14 |