오늘한 일
- [항해 99] 실전 프로젝트 상세 1페이지 필터 구현
- [항해 99] 실전 프로젝트 상세 1페이지 필터 팁(?) 구현 진행중
내일 할 일
- 리액트 쿼리 1강 다 듣기
- [항해 99] 실전프로젝트 상세 1페이지 필터 팁 부분 구현 완료
- [항해 99] 실전프로젝트 마이메이지 와이어프레임 css 작업
오늘의 배운 점
상세 1페이지에서 필터 한 산 리스트 불러오기(api 명세서의 이름 변경 이슈로 어렵게 구현함)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
//이상하게 짰던 코드(slice 부분) async (payload, thunkAPI) => { try { const { data } = await axios.post( `${process.env.REACT_APP_AXIOS_API}/api/mountains/filter`, payload ); const result = data.data.filter((item) => { return ( item.region.includes(payload.mountainRegion) && item.season.includes(payload.mountainSeason) && item.level.includes(payload.mountainLevel) ); }); return thunkAPI.fulfillWithValue({ result }); //mountainList.jsx {mountains.result ? mountains.result?.map((mountain, index) => { return ( <div key={index}> <Mountain mountain={mountain} /> </div> ); }) : mountains.data?.map((mountain, index) => { return ( <div key={index}> <Mountain mountain={mountain} /> </div> ); })} //---------------------------------------------------------------------- //올바른 slice 부분 async (payload, thunkAPI) => { try { const { data } = await axios.post( `${process.env.REACT_APP_AXIOS_API}/api/mountains/filter`, payload ); return thunkAPI.fulfillWithValue(data); //mountainList.jsx {mountains.data?.map((mountain, index) => { return ( <div key={index}> <Mountain mountain={mountain} /> </div> ); })}
일단 이상하게 짜게 된 이유는 ERD가 변경되면서 생겨난 문제였다. 멘토님의 피드백으로 원래 mountainRegion처럼 산 관련된 부분들에는 모두 mountain이 들어간 상태였는데, 멘토님은 어쨌든 산에 대한 ERD들이기때문에 굳이 mountain을 안써도 된다고 하셨고 ERD에서 산 쪽의 field에서 mountain이 빠지면서 region같이 뒷 부분만 쓰면 되는 것을.. 이해를 잘못해서 그냥 mountainRegion으로 name이 들어가면서 생긴 오류였고, 서버팀에 확인해본 결과 이 부분에 있어 내가 이해를 잘못하고 진행했다는 것을 깨닫고 일반적으로 사용하는 post 형식으로 진행하니 간단한 코드로 쉽게 해결되었다.
++ 이상한 코드의 경우 filter로 걸러낼 때 region에 입력된 필터값과 같은 value가 있는지 찾아보고 해당 리스트를 뽑아내는 형식으로 진행했다. 이렇게 진행하면 이후 본 MountainList 부분에서도 처음에 불러오는 get과 따로 filter된 리스트를 불러오는 작업이 필요하기때문에 문제가 있다고 판단을 했다.
상세 1페이지 팁 구현 진행 중(칩 삭제 시 정보 삭제되는 부분 구현 실패 상태-수정예정)
여기서 중요하지 않은 부분은 삭제한 상태 -> 필터는 4가지 종류이나 길어서 두 개만 입력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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
//slice.jsx const initialState = { isseason: false, isregion: false, }; export const mountainsSlice = createSlice({ name: "mountains", initialState, reducers: {}, reducers: { //필터 칩 - 선택확인(상태관리) isSeasonFalse: (state) => { state.isseason = false; }, isRegionFalse: (state) => { state.isregion = false; }, }, extraReducers: { [__postFilterMountains.fulfilled]: (state, action) => { state.filter = action.meta.arg; state.mountains = action.payload; //filter에 따라 뜨도록 설정(전역관리) if (Object.keys(action.meta.arg).includes("season")) { state.isseason = true; } if (Object.keys(action.meta.arg).includes("region")) { state.isregion = true; }, [__postFilterMountains.rejected]: (state, action) => {}, }); export const { isSeasonFalse, isRegionFalse, isTimeFalse, isLevelFalse } = mountainsSlice.actions; //filterResult.jsx import styled from "styled-components"; import { useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { __postSearchMountains, isSeasonFalse, isRegionFalse, } from "../../redux/modules/mountainsSlice"; const FilterResult = () => { const dispatch = useDispatch(); //필터 칩 관련 전역 관리 const filters = useSelector((state) => state.mountains.filter); const isfilters = useSelector((state) => state.mountains); //필터 칩 x 눌렀을 때 칩 사라짐 효과 const onSeasonDelBtn = () => { dispatch(isSeasonFalse()); }; const onRegionDelBtn = () => { dispatch(isRegionFalse()); }; return ( <StFilterResult> <div> {isfilters.isregion ? ( <div> {filters.region} <button value="region" onClick={onRegionDelBtn}> x </button> </div> ) : null} </div> <div> {isfilters.isseason ? ( <div> {filters.season} <button onClick={onSeasonDelBtn}>x</button> </div> ) : null} </div> </StFilterResult> ); }; export default FilterResult;
코드 간략화하려고 고민을 많이 해봤는데 아무리 해봐도 지금 상태에서 서버의 도움이 없이는 더 이상 간략화는 어려울 것 같다는 생각이 들었다.
현재 상태는 필터를 하는 component와 산 리스트를 불러오는 component, 필터의 칩(결과상태)을 보여주는 component가 props 형태로 이어질 수 없는 형제요소 상태로 연결되어 있어 props를 사용하지 못한 채로 진행하다보니 대부분의 내용들을 slice에서 전역으로 관리를 하고 해당 부분을 불러와 사용하는 방법으로 진행했다.
필터가 1개이면 비교적 쉬울 것 같은데 4가지나 있다보니 각각 다르게 설정을 해줘야해서 코드가 조금 더 길어진 상태.
++Object.keys는 현재 객체 상태인 res를 배열형태로 변환하여 includes를 사용할 수 있게 해준다. 여ꈰ서 includes를 사용하는 이유는 각 필터에 맞게 isseason 등으로 상태관리를 하기 위해서이다. 값이 들어가지 않은 false 상태일 때는 해당 칩이 뜨지않게, 값이 들어간 true 상태일 때는 칩이 뜨도록 하기 위해 상태관리는 여ꈰ서 해줬다.
이렇게 만든 칩들은 x 버튼을 누르면 사라지면서 해당 칩이 없는 상태의 리스트가 뜨는게 정상이지만 아직 해당 정보를 삭제하는 부분까진 구현하지 못해서 해당 부분은 구현하는 대로 정리해서 올릴 예정
요즘 실전프로젝트 작업한다고 정신이 없어서 TIL을 올릴 겨를이 없다. 나름 꾸준하게 올리려고 하는데, 멘탈이 터지거나 혹은 작업에 치여서 도저히 정리가 안되는 상태가 일상의 90%를 차지하다보니.. 이제는 다른 사람들에게 물어보면서 진행하는 부분을 최소한으로 해서 혼자 작업을 하다보니 작업 속도는 더디고 이해가 안되서 머리가 터질 것 같다. 이번 필터도 결국 여기저기 물어보면서 작업했다.
성격이 급하다보니 중간 중간에 빼먹은 내용들 때문에 생기는 이슈들이 있는 것 같아서 좀 더 코드를 꼼꼼하게 보는 습관을 길러야 할 것 같다.
사실 머리 속에서 로직이 도저히 생각이 안나면 서버팀에 가서 해당 api에 대해 물어볼 때가 많은데, 항상 보면 내가 실수한 상태, 혹은 백엔드에 대한 이해가 부족하다보니 생기는 문제들이 많은데 이런 부분들은 어떻게 하면 수월하게 해결할 수 있을지 모르겠다.
이제 슬슬 마음은 급한데 머리랑 손이 안따라가주니까 헛손질 하는 느낌이 드는데, 그래도 뭐 해봐야겠징.. 징징이는 징징거리는중…….징징..
한동안 그럴 수 있지 마인드를 잘 가져가고 있었는데 예민해지니까 그런 마음을 가지기 쉽지않다.
다시 한 번 그럴 수 있지 마인드 장착하고 열심히 도전해야겠다.. 열심히 하면 어떻게든 되겠지 뭐..
좀 더 열심히 해보자!!