https://xionwcfm.tistory.com/356
이전 게시물에 대한 답변
쿼리셀렉터로 직접 돔제어를 하는 부분은 조금 사연이 있었는데
이 이야기를 하자면 useForm 이야기를 하지 않을수가 없다.
useForm이 반환하는 register 함수의 반환값은 총 네가지로
onChange, onBlur, ref, name이 있는데
이 register가 반환한 ref를 기반으로 원하는 인풋엘리먼트에 접근할 방법을 도저히 모르겠는것이다.
그런데 나는 이메일 인증 요청하기 버튼을 누르기전까지는 입력버튼을 비활성화하고
요청이 성공적으로 서버에 전달되었을때 입력버튼을 활성화시켜주고 싶었는데
그러기위해서는 특정 input을 조작해야했던것
멘탈이 박살나있었는지 결국 querySelector를 통해 직접 돔을 조작해버렸지만
하면서도 안티패턴이라는 생각이 들긴했다.
그런데 다시 생각해보니 리액트에서도 disabled = {true/false} 형태로 disabled값을 조작할 수 있었던 것.
결국 useState를 하나 더 만들어 disabled 값을 리액트에서 조작하도록 리팩토링했다.
예쁜 코드는 희망일 뿐일까?
항상 내가 디자인도 짜는 입장이어서 개발자 친화적이게 디자인과 기능을 구성하고 개발하다보니
이번처럼 추상화 시키기 어려운 케이스를 구현해야한 것은 처음이었다.
마음 같아서는 그냥 다 통일해버리고 깔끔하게 반복을 돌리고 싶었지만
현실적으로 가능하지 않은 경우에는 어쩔 수 없지 않나? 싶은 느낌이다.
그럼에도 불구하고 클린하게 코드를 작성하려면 어떻게 해야할까?
멘토님은 관심사분리를 말씀해주셨는데 관심사 분리의 중요성에 대해서는 전적으로 공감을 하기도하고
필요성을 느끼지만 많은 수정소요가 발생하는 개발단계에서는
오히려 여러갈래로 사혼의 구슬조각마냥 퍼져버린 로직들을 찾아 파일을 옮겨다니는 일이
굉장히 개발속도를 떨어뜨린다는 생각이 들었다.
미래에는 개발 스타일이 달라질 수도 있겠지만
지금은 한파일에 우선 모든걸 몰아넣어 개발한 다음
어느정도 구조에 견고함이 생겨 세부사항은 간단하게 값만 바꿔 넣어주면 되는 시점일 때
분리하는 형태를 취하고 있는데 지금으로서는 베스트 프래티스라고 생각한다.
물론 그런 와중에도 내 나름의 네이밍컨벤션을 정하고
한 파일 내부에서도 관심사를 분리하기 쉽게 코드를 작성하려 노력하고있다.
예컨대 지금 만들고있는 여러가지 폼들은 각각 세부요구사항은 다르지만
필요한 행동들은 거진 비슷한 형태인데 정리하면 다음과 같다.
1. 사용자의 제출결과를 서버에 전달하기 위한 Post 로직이 필요하다
2. schema를 기반으로한 유효성검증 로직이 들어가야한다.
3. 폼 제출을 컨트롤할 수 있도록 인풋을 제어하고 제출하는 로직이 필요하다
4. (당연하게도..) 시각적으로 표현할 view도 있어야한다.
5. view들을 의미있게 나열해주고 라우팅포인트가 될 컴포넌트가 필요하다.
1번 같은 경우에는 react-query를 커스텀훅으로 만들어 사용하고있다.
사실 Post만 잘 보내지면 응답은 그리 크게 중요하지않은 것들도 다 리액트쿼리 커스텀훅으로 만들고있어
이게맞나... 싶은 느낌이긴하다.
굳이 상태로 관리할 필요가 없는 녀석들도 리액트쿼리에 담을 필요가 있을까?
이건 좀 고민이 필요할 것 같다.
2. 이건 zod를 이용하여 유효성검증을 수행하고 있다.
zod는 내 코드에 가장 많은 영향을 끼친 유튜버가 있는데 josh tried coding이라는 채널을 운영하는 일인 유튜버가 있다.
이 유튜버에게서 zod를 알게되었는데 직관적인 문법이 마음에 들기도하고
react-hook-form과의 통합도 쉬워 적극적으로 사용하고 있는 라이브러리다.
추후에는 zod로 작성한 schema만 모아둔 폴더를 생성해 분리시켜줄 계획이다.
3. 이 경우에는 react-hook-form이 제공하는 useForm을 이용해 해결하고 있다.
useState로 관리하는 것은 정석적인 방법이지만 회원가입과 같은 복잡한 폼을 다뤄야하는 경우에는
로직이 어려운 것도 아니면서 굉장히 장황해지는 문제가 있기때문이다.
이미 useForm을 호출하는 것만으로 관리를 대신하고 있기때문에 분리시킬 필요성이 있을까?에 대한 고민이 있다.
제출할때의 행동을 작성하는 부분을 컴포넌트 내부에서 수행하는게 조금 걸리긴한다.
4. view는.. 컴포넌트에서 작성할 수 밖에 없다.
5. 현재는 페이지 컴포넌트에서 모든 로직을 한번에 다 작성하고있는데
추후 로직이 견고해지면 컴포넌트들을 나누어 줄 예정이다.
프론트엔드에서 관심사분리를 완벽하게 이루어내는 것은 매우 어렵다고 생각한다.
실제로 코드를 작성하다보면 느끼게 되는 것이지만
현실적으로 관심사 분리를 완벽하게 이루어낼 수 없는 경우가 왕왕 존재한다.
예컨대 라우팅과 컴포넌트를 나열하는 일을 수행할 페이지 컴포넌트는
라우팅과 컴포넌트 나열만 수행하면 좋겠지만 현실적으로는 반드시 페이지 컴포넌트에서
useEffect를 호출해야하는 경우 등 이루어지지 않는 경우가 많은 것 같다.
이건 조금 사설) 커스텀훅을 통해 복잡한 로직을 컴포넌트에서 분리시키고
컴포넌트단에서는 커스텀훅을 사용하기만 하는 방법을 지향하고 있는데
ref를 통해 끈끈하게 htmlelement들과 결합해서 사용되어야하는 커스텀훅을 작성하는 것은
아직도 꽤 어렵게 느껴지곤 하는 것 같다.
결론
세부적인 구현은 숨기고 무엇을 하는지를 잘 나타내어 쉽게 읽을 수 있는 코드를 작성하는 것이 중요하다고 생각한다.
가능하다면 깔끔하게 반복문을 돌리고 콘텐츠들은 외부에서 주입받는 형태로 쓰고싶은게
개발자의 마음일 것 같지만 현실적으로 모든 코드를 그렇게 작성할 순 없다는 것을 배웠다.
그럼에도 불구하고 선언적인 코드를 작성해나갈 수 있는 방법을 좀 더 고민해봐야겠다.
'프로젝트 진행기' 카테고리의 다른 글
[Plip] 이메일 요청은 되도록 한번만 보내주세요 (0) | 2023.07.24 |
---|---|
[PliP] 로그인의 restful 한 설계와 토큰 관리 전략 (1) | 2023.07.19 |
너무 복잡도가 높은 컴포넌트는 어떡하면 좋을까? (1) | 2023.07.05 |
[Solo Project] 재사용성을 고려한 설계 (1) | 2023.05.19 |
[SoloProject] Toast Side Effect issue (0) | 2023.05.17 |