useEffect()
사용
// 컴포넌트 내부
const data = useSelector((state) => state.data);
useEffect(() => {
fecth(API_URL, {
method: 'POST',
body: JSON.stringify(data),
});
}, [data]);
useEffect()
문제 : 앱이 시작될 때 실행됨
=> 코드 수정
// 컴포넌트 외부
let isInitial = true; // 컴포넌트가 리렌더링돼도 다시 초기화되지 않음 (파일이 처음으로 parse될 때 초기화)
// 컴포넌트 내부
const data = useSelector((state) => state.data);
useEffect(() => {
const sendData = async () => {
const response = await fecth(API_URL, {
method: 'POST',
body: JSON.stringify(data),
});
if (!response.ok) {
// 실패 처리
}
// 성공 처리
};
if (isInitial) {
isInitial = false; // 앱이 처음 시작될 때만 sendData() 차단
return;
};
sendData();
}, [data]);
작업 생성자(action creators)를 생성하여 비동기 코드 실행
thunk
: 다른 작업이 완료될 때까지 작업을 지연시키는 단순한 함수
작업 객체를 즉시 반환하지 않는 작업 크리에이터를 작성하기 위해 thunk로 작업 크리에이터를 작성
=> 작업을 반환하는 다른 함수를 반환
원래 만들려고 했던 실제 작업 객체를 dispatch하기 전에 다른 코드 실행
// 별도의 함수
// 함수를 반환하는 action creator
export const fetchData = () => {
return async (dispatch) => {
const sendRequest = async () => {
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error('Could not fetch data');
}
const data = await response.json();
return data;
};
try {
const data = await sendRequest();
dispatch(ACTIONS.ACTION_CREATOR(PAYLOAD))
} catch (error) {};
};
};
export const sendData = (data) => {
// 아직 리듀서에 도달하지 않았으므로 비동기 코드 수행 가능
return async (dispatch) => {
const sendRequest = async () => {
const response = await fecth(API_URL, {
method: 'POST',
// body: JSON.stringify(data),
body: JSON.stringify({/* 새 객체 생성 */}),
});
if (!response.ok) {
// 실패 처리
}
// 성공 처리
};
try {
await sendRequest();
dispatch(ACTIONS.ACTION_CREATOR(PAYLOAD)));
} catch (error) {}
};
};
// 컴포넌트 내부
const dispatch = useDispatch();
const data = useSelector((state) => state.data);
useEffect(() => {
dispatch(fetchData());
}, [dispatch]);
useEffect(() => {
if (isInitial) {
isInitial = false;
return;
}
if (data.changed) {
dispatch(sendData(data)); // 다른 함수를 반환하는 함수를 전달
}
}, [data, dispatch]);