개발자
안녕하세요!! 현재 진행 중인 프로젝트에서 회원가입 시 필요한 정보를 입력하는 중 새로고침 시 session 및 localstorage를 이용하여 상태유지를 하려고하는데 recoil과 관련하여 atom effect를 사용하면 우아하게 처리할 수 있음을 알았습니다. 따라서, 각 atom에 effect를 하나하나 추가하는 방법을 생각했는데 동일한 logic을 행하는 코드의 양이 방대해지고 localstorage에 각 atom에 해당하는 key-value로 저장되므로 가독성 측면에서 좋지 않다고 판단하여 아래와 같은 과정을 생각했습니다. 각 atom을 하나로 묶어 객체로 관리하자. 객체로 관리하게 되면 불필요한 re-rendering이 촉발되므로 객체로 선언한 atom의 각 property에 접근 및 수정을 위한 selector를 정의하자. 객체에 내의 property에 1대1로 selector를 정의하면 객체로 묶기 전 atom의 갯수만큼 selector를 선언해주어야 하므로 selectorFamily를 사용하자. 이것저것 찾아보면서 1 → 2 → 3 단계로 생각을 정리했습니다. 아래는 현재 사용되는 atom입니다. <ATOM> // signup.store.ts 👇 회원가입에 대한 user state들 - SignUpProfileTypeAtom - SignUpProfileRentalTypeAtom - SignUpProfileRegionsAtom - SignUpProfileDepositPriceAtom - SignUpProfileTermAtom - SignUpProfileMonthlyPriceAtom - SignUpProfileSmokingAtom - SignUpProfilePetAtom - SignUpProfileAppealsAtom - SignUpProfileGenderAtom - SignUpProfileMatesNumberAtom - SignUpProfileMateAppealsAtom // 👇 위의 atom들을 한 번에 access 및 update - SignUpProfileSelector 하지만, 다른 팀원이 저렇게 atom을 구성한 상황 제 생각을 그대로 적용하고자하면 팀원의 코드를 마음대로 바꾸는 거 같아서 조심스럽습니다. 협업함에 있어 설득도 하나의 중요한 스킬임을 갈수록 깨닫게 됩니다.(다들 어떻게 설득하시나요?) 팀원이 기존의 코드는 안 바꿨으면 좋겠다 하면 각 atom에 effect를 추가하는 것이 맞겠죠???? 현재 현업에 계신 분들은 이러한 상황에서 어떻게 설득하며 어떻게 하는 것이 좋을까 자문을 구하고 싶어서 글 올려봅니다!!🥲🥲 짧지 않은 글이지만 읽어주셔서 감사하고 많은 의견 주시면 감사하겠습니다!!😄😄😄 ```typescript import { SignUpType } from '@/types/signUp.type'; // ? type 집 유형 0: 원룸/오피스텔, 1: 빌라/연립, 2: 아파트, 3: 단독주택 @number export const SignUpProfileTypeAtom = atom<SignUpType['type']>({ key: 'signUpProfileTypeAtom', default: undefined, }); // ? rental_type 집 대여 유형 0: 월세, 1: 전세, 2: 반 전세 @number export const SignUpProfileRentalTypeAtom = atom<SignUpType['rental_type']>({ key: 'signUpProfileRentalTypeAtom', default: undefined, }); // ? regions 유저가 찾는 지역 >도시 (region) + 구(district) 형태의 배열 @string[] export const SignUpProfileRegionsAtom = atom<SignUpType['regions']>({ key: 'signUpProfileRegionsAtom', default: [], }); // ? deposit_price 보증금 (전세 혹은 월세) 범위 [최소 금액, 최대 금액] (0만원~10000만원) @[number, number] export const SignUpProfileDepositPriceAtom = atom<SignUpType['deposit_price']>({ key: 'signUpProfileDepositPriceAtom', default: [0, 10000], }); // ? term 유저가 살 기간 [최소기간, 최대 기간] (0 ~ 24)범위 @[number, number] export const SignUpProfileTermAtom = atom<SignUpType['term']>({ key: 'signUpProfileTermAtom', default: [0, 24], }); // ? monthly_rental_price 월세 [최소 금액, 최대 금액] (0만원, 500만원) @[number, number] export const SignUpProfileMonthlyPriceAtom = atom<SignUpType['monthly_price']>({ key: 'signUpProfileMonthlyPriceAtom', default: [0, 500], }); // ? smoking 흡연 여부 @boolean export const SignUpProfileSmokingAtom = atom<SignUpType['smoking']>({ key: 'signUpProfileSmokingAtom', default: undefined, }); // ? pet 펫 여부 0: 상관없음, 1: 좋음, 2: 싫음 @number export const SignUpProfilePetAtom = atom<SignUpType['pet']>({ key: 'signUpProfilePetAtom', default: undefined, }); // ? appeals 유저의 어필할 매력(배열형태) @string[] export const SignUpProfileAppealsAtom = atom<SignUpType['appeals']>({ key: 'signUpProfileAppealsAtom', default: [], }); // ? gender 상대방의 성별 0: 상관없음, 1: 남성, 2: 여성 @number export const SignUpProfileGenderAtom = atom<SignUpType['gender']>({ key: 'signUpProfileGenderAtom', default: undefined, }); // ? mates_number 인원수 0: 상관없음, 1: 1명, 2: 2명, 3: 3명이상 @number export const SignUpProfileMatesNumberAtom = atom<SignUpType['mates_number']>({ key: 'signUpProfileMateNumberAtom', default: undefined, }); // ? mate_appeals 유저가 원하는 상대방의 매력 (배열형태) @string[] export const SignUpProfileMateAppealsAtom = atom<SignUpType['mate_appeals']>({ key: 'signUpProfileMateAppealsAtom', default: [], }); ```
답변 1
안녕하세요 답변 드립니다. 😏 기존 사용하는 방법이나 새로운 방법 둘 다 상관은 없을 것 같지만 되도록 한 프로젝트에서는 같은 방식으로 진행 하는 게 좋을 것 같습니다. 바꾸실 꺼면 전체를 다 바꾸시는 게 좋을 것 같습니다. 재 사용을 위해 만들고 재 사용되지 않는 로직은 효율적이라도 크게 의미가 없을 것 같습니다. 그리고 제가 리코일은 사용해 본 적이 없어 잘 모르겠지만 userInfo 하나에 다 정리해서 넣을만한 내용인 것 같은데 저렇게 분리되어야지 더 좋은 구조일까요? 리액트 기반에 리코일 이라면 객체 내 데이터가 화면을 구성하는 요소랑 관계가 없을 때 리랜더링이 일어나지 않았던 것 같은데 🤔 또한 정리된 내용들이 굳이 다 상태 관리로 분리해야 될지도 약간 의문이 듭니다. 어차피 업데이트된 내용이라면 백엔드에 post를 통해 유저의 상태를 업로드 하게 되고 이후 해당 info가 다시 필요하게 된다면 백엔드에 get을 호출 하는 게 더 좋습니다. (너무 빈번하지 않다면요) 상태 관리를 통해 통신을 적절히 최적화하고 횟수를 줄이는 선택은 나쁘지 않지만 서버의 정보와 유저의 정보가 동일하지 않게 되는 시점이 발생할 수 있고 (통신 에러, 로직 에러, 중간에 끄던지 등의 통신 차단) 이러한 정보를 모두 상태 관리로 관리하게 되면 불일치가 일어날 수 있습니다. 요약하자면 한 프로젝트에서는 협의하 통일된 상태 관리 룰을 사용 하는 게 좋으며 현재 사용하는 상태 관리가 과연 필요한 것인지, 가입이나 설정 페이지에서 단순히 useState정도로 끝날 내용이 아닐 지에 대한 고민이 필요할 것 같습니다. + 잘 읽어보니 리랜더링이 요점인지 새로 고침 시의 정보 보존이 목표 인지부터 조금 애매한 듯 하네요 새로 고침 시 정보 유지의 경우 필요하다면 단순히 localStorage와 연결해서 구현 가능합니다. redux나 recoil에서 persist와 같은 라이브러리로 상태 관리 중인 값을 localStorage에 단순 연동도 가능하지만 정보 유지를 위해 기존 useEffect나 변수를 꼭 상태 관리를 거쳐야 하지는 않습니다.
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!