본문 바로가기

전체 글84

노션 링크 https://luminous-trapezoid-0f1.notion.site/Fineday-gangwon-c5ece2b4280149c58a22c9ca198510f7?pvs=4 2024. 3. 12.
문제해결_ 공공 데이터의 배신 ( 숫자여야만 하는데…) 간혹 실시간 데이터나 과거 데이터의 일부지역 의 미세먼지 값이 null 또는 ‘ - ‘로 들어올때가 있어서 그래프와 계산 로직에 악영향을 준다. 그래서 실시간 데이터 값이 숫자가 아닌 경우는 다른 지역의 데이터로 대체해주는 것을 피할 수 없었다. 실시간 미세먼지 수치에서는 일부지역에서 숫자가 아닌 값이 들어와서 그럴때는 강릉의 value를 넣어줬다. const { data, isError, isLoading, refetch } = useQuery( 'dustData', fetchDustData, { // onSuccess ->useQuery에서 사용함. 비동기 요청 성공시 실행되는 콜백함수 정의! onSuccess: data => { // 데이터 fetch 성공 시, Recoil Atom 업데이트, 5개.. 2024. 3. 12.
문제해결_사용자 경험을 향상시키기 위해 ( useEffect ) 현재 날씨가 좋은 지역을 리코일 전역상태로 넣었는데, 실시간이다 보니(30분 주기로 바꾸었지만) 데이터가 자주 바뀌어서 사용자에게 불편한 경험을 하게 할것 같았다. 메인뷰의 지역 셀렉트박스의 필터는 마운트될때 한번만 적용시키고 그 외에는 적용이 안되도록 해보았다. useEffect(() => { // 컴포넌트가 마운트될 때 현재 추천지역 Recoil 상태를 로컬 상태의 초기값으로 설정 setSelectedValue(defaultLocationName); // 의존성 배열을 빈배열로 두어, 리코일상태가 변하더라도 영향 받지 않음 }, []); 차트 컴포넌트와 기록 컴포넌트의 부모 컴포넌트인 MainView 컴포넌트에서 의존성배열을 빈배열로만 두면 된다. 2024. 3. 12.
문제해결_ SPA스러운 UI ( useLocation과 useNavigate) 메인페이지 하위의 기록 컴포넌트에서 기록을 하거나 새로고침 하면 차트 컴포넌트로 자꾸 바뀐다. 일반적으로 페이지 구분이 될경우 url로 경로를 관리해 뒤로가기 해도 이전에 머물렀던 페이지로 돌아가지만tab으로 구성된 것이라 url경로 관리는 불가했다. tab 컴포넌트는 url과 별개로 독립적으로 작동하기 때문이다. url과 tab 컴포넌트 상태를 연동해서 동작을 조정할 수 있는것을 알았다. useLocation과 useNavigate 훅을 사용하고, url의 쿼리 파라미터나 경로의 일부분으로 현재 선택된 탭을 나타내는 방법을 고려했다. 쿼리스트링 라이브러리로 tab1, tab2의 경로로 나누었다. 기록을 저장완료해도 기록 컴포넌트에 잘 머문다! 2024. 3. 12.
문제해결_ 코드가 길어지면 props도 헷갈린다.( 객체구조분해할당 ) 홈화면에서 메인화면으로 입장하면 현재 추천 지역이 상단 문구에 뜨고, 해당 지역의 미세먼지 추세 그래프가 뜬다. 페이지별로 화면을 구성하는 것은 리액트의 장점을 못살리는 UI라고 생각했다. 메인화면 내부의 컴포넌트를 바꿔주는 형식으로 디자인을 구성했는데, 필터도 필요하고 다이어리(기록)부분으로 컴포넌트를 바꿀때 상단의 필터를 어떻게 처리해줘야 효율적일지 고민했다. 단순하게 페이지별로 나누고싶은 욕구가 들었다. 차트 컴포넌트와 기록 컴포넌트를 감싸는 상위 컴포넌트인 메인뷰에는 지역 셀렉트박스(필터)가 있는데, 홈에서 메인으로 넘어올 경우 현재 추천 지역을 디폴트 값으로 넣어주고, 해당지역의 미세먼지 추세를 그래프로 보여준다. 필터의 지역은 props로 하위 차트 컴포넌트와 기록 컴포넌트에도 전달을 해주는데.. 2024. 3. 12.
문제해결_ 리코일을 처음 사용해보니…( 결국엔 로컬 스토리지2 ) 홈 페이지에서 메인 페이지로 들어가면 현재 추천 지역의 그래프가 뜨도록 설정했다. 프롭스로 지역만 넘겨주면 된다고 생각했다. const MainView = () => { const defaultSelectedValue = useRecoilValue(currentSpotAtom); const [defaultLocationName, defaultDustLevel] = defaultSelectedValue; // 지역 필터 선택 const [selectedValue, setSelectedValue] = useState(defaultLocationName); // 데이터 피커 기록텝에서만 보이기 const [selectedTab, setSelectedTab] = useState('1'); useEffect(().. 2024. 3. 12.
문제해결_ 공공데이터 일일 트래픽 초과 ( 결국엔 로컬 스토리지1 ) 지역별 과거 일평균 미세먼치 데이터는 데이터는 하루 한번만 요청하면 되기때문에 이걸 로컬에 저장하고 재사용하도록 했다.(saveDataToLocalStorage) 공공데이터 일일트래픽이 있는데 만들다보니 의도치 않게 초과하여 데이터가 나오지 않는다. useQueries에서는 직접적으로 로컬 스토리지 데이터의 유효성을 검사하고, 이를 기반으로 쿼리 실행 여부를 결정하는 것은 안된다. 대신, 로컬 스토리지에서 데이터를 불러오는 로직을 쿼리 함수 내에서 직접 구현하거나, 쿼리 실행 전에 데이터의 유효성을 검사하여 쿼리 실행 여부를 결정하는 로직을 외부에서 처리해야한다. 로컬 스토리지에 저장된 데이터가 오늘 날짜에 해당하는지 확인하고, 만약 오늘 날짜의 데이터가 없거나 유효하지 않은 경우 API를 호출하여 데이.. 2024. 3. 12.
문제해결_ Recoil과 API 통신의 비효율성 위의 그래프를 구현 하려면 지역별 과거 미세먼지 수치 일평균의 값을 받아와서 로직(지역별 7일간의 평균과 순위)을 통해 값을 추출하여 넣어야하는데 리코일을 사용하려고 찾아보니 뭔가 이상하다. 리코일은 api통신관련 비효율적이라 리액트 쿼리 라이브러리로 api통신 데이터를 관리하는게 효율적이라는 조언을 들었다. 리코일만 신경쓰다가 너무 편향적으로 코드를 짜려고 노력한것이다. 그래도 셀렉터까지 공부할수 있었으니 좋은 기회였다고 생각하고 현재의 코드는 셀렉터에 api호출하는것을 넣어두고 컴포넌트에서 해당 셀렉터로 api통신해서 값을 가져오거나, atom에 저장해서 다른 컴포넌트에 전달해주는 역할을 했다 다시금 내용을 정리해서 리액트쿼리로 api통신 관리 → api 캐싱, 업데이트 등 효율적임 리코일 아톰을 사.. 2024. 3. 12.
 상태 관리 - 전역 데이터를 위한 Recoil API를 통해 받아온 데이터를 가공하여 필요한 컴포넌트에서 잘 사용하기 위해서 전역적으로 데이터를 관리할 상태관리 툴이나 context API가 필요해졌다. context API는 전역 상태를 전달할 때 객체 형태의 value를 사용한다. 따라서 객체 안의 값이 하나라도 변경되면 provider로 감싼 모든 하위 컴포넌트들이 리랜더링한다는 단점이 있다. 작은 프로젝트일 경우 좋다. 대표적인 상태관리 툴인 Recoil의 경우 각각의 전역 상태에 대한 atom이 생성되고 해당 상태를 구독하는 구성 요소만 리랜더링 된다. 따라서 불필요한 리랜더링을 방지할 수 있다. 리액트의 장점을 살리려면 상태관리 툴을 사용하는 것이 좋아보였다. 프로젝트의 경우 여러페이지에서 api로 받아온 데이터를 사용하기 때문에 리코일을.. 2024. 3. 12.