버튼을 한번 클릭했을 때는 ui 렌더링이 안되고 두번 클릭했을 때 렌더링이 된다
한번 클랙했을 때는 searchparams로 url 주소는 변경되지만 그 어떤 state도 변경되지 않기 때문에 리렌더링은 되지 않는다.
원래 작성했던 이슈 가득한 코드
import React, { useEffect, useState } from 'react';
import { useSearchParams, useLocation } from 'react-router-dom';
import Header from '../Header/Header';
import Map from '../Map/Map';
import './Main.scss';
const Main = () => {
const location = useLocation();
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
const [dongData, setDongData] = useState([]);
useEffect(() => {
fetch('http://서버/regions')
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
}, []);
const sortStore = storeName => {
if (location.search.includes('application')) {
const application = searchParams.get('application');
setSearchParams({ store: `${storeName}`, application });
} else {
setSearchParams({ store: `${storeName}` });
}
const url = location.search;
console.log(url);
fetch(`http://서버/regions${url}`)
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
};
const sortApplication = appName => {
if (location.search.includes('store')) {
const store = searchParams.get('store');
setSearchParams({ store, application: `${appName}` });
} else {
setSearchParams({ application: `${appName}` });
}
const url = location.search;
fetch(`http://서버/regions${url}`)
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
};
const showAllStoreData = () => {
location.search.includes('store', 'application') &&
searchParams.delete('store', 'application');
setSearchParams(searchParams);
fetch(`http://서버/regions${searchParams}`)
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
};
const showAllAppData = () => {
location.search.includes('application') &&
searchParams.delete('application');
setSearchParams(searchParams);
fetch(`http://서버/regions?${searchParams}`)
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
};
if (dongData.length === 0) return;
return (
<>
<Header
dongData={dongData}
sortStore={sortStore}
sortApplication={sortApplication}
showAllAppData={showAllAppData}
showAllStoreData={showAllStoreData}
/>
<Map dongData={dongData} />
</>
);
};
export default Main;
수정된 코드
import React, { useEffect, useState } from 'react';
import { useSearchParams, useLocation } from 'react-router-dom';
import Header from '../Header/Header';
import Map from '../Map/Map';
import './Main.scss';
const Main = () => {
const location = useLocation();
const [searchParams, setSearchParams] = useSearchParams();
const [dongData, setDongData] = useState([]);
const url = location.search;
useEffect(() => {
fetch(`http://서버/regions${url}`)
.then(res => res.json())
.then(data => {
setDongData(data.result);
});
}, [url]);
const sortStore = storeName => {
if (location.search.includes('application')) {
const application = searchParams.get('application');
setSearchParams({ store: `${storeName}`, application });
} else {
setSearchParams({ store: `${storeName}` });
}
};
const sortApplication = appName => {
if (location.search.includes('store')) {
const store = searchParams.get('store');
setSearchParams({ store, application: `${appName}` });
} else {
setSearchParams({ application: `${appName}` });
}
};
const showAllStoreData = () => {
location.search.includes('store', 'application') &&
searchParams.delete('store', 'application');
setSearchParams(searchParams);
};
const showAllAppData = () => {
location.search.includes('application') &&
searchParams.delete('application');
setSearchParams(searchParams);
};
if (dongData.length === 0) return;
return (
<>
<Header
dongData={dongData}
sortStore={sortStore}
sortApplication={sortApplication}
showAllAppData={showAllAppData}
showAllStoreData={showAllStoreData}
/>
<Map dongData={dongData} />
</>
);
};
export default Main;
useEffect에서 의존성 배열 안에 무엇을 작성할 수 있나?
일단 로직을 따져보자
url주소에 변화가 생기면 바로 fetch를 불러라 렌더링은 어차피 fetch함수 안에 dongData를 업데이트 시키는 state가 있기 때문에 리렌더링 될 것이다.
그럼 url 주소에 변화가 생길때마다 fetch함수를 불러오면 된다.
useEffect에서 의존성 배열에 state만 쓸 수 있는게 아니다
의존성 배열에 작성하는 것이 변화할 때마다 useEffect 함수는 작동한다.
그럼 url 을 먼저 선언해주고
url에 변화가 생길 때마다 그 url을 주소 뒤에 넣어 서버에 요청한다.
그 url을 의존성 배열에 작성한다.
즉 의존성 배열에는 변수도 작성할 수 있다.
일단 fetch 함수를 딱 한번만 사용한다는 깔끔함에 걸렸던 병이 나았다.