정글에서 살아남기

 

 

지나온 과거에 대한 성찰

  입대 전까지는 개발의 근간에 대해 고민하지 않고 그저 앞에 닥친 문제를 해결하기 위해 애쓰는 하루의 연속이었다. 나름 애쓰다 보니 눈 앞의 문제들은 어느정도 해결할 수 있었다. 하지만 일을 하면 할 수록 내가 만든 것들의 동작에 대한 이해 없이는 더 레벨업하기 힘들겠다는 것이 느껴졌다. 그러던 와중 갑작스런 입대를 하게 됐다.

 

  군복무 하며 이런 나의 부족한 cs 지식을 채우고 싶었다. 하지만 달마다 1~2주의 훈련이나 휴가를 다녀오면 공부의 맥락이 끊기기 일수였다. 아무리 책을 붙들어도 연속성이 떨어져 머리에 남는게 없었다. 공부 내용과 방법에 대해 시행착오를 하느라 많은 시간이 소비되었다. 한창 사회활동 할 시기에 군복무 중인 것도 너무 시간 아까운데 공부마저 내 마음대로 안되자 배움에 대한 아쉬움은 더욱 커져만 갔다.

 

5개월 동안 얻어가고 싶은 것

  그러던 중 정말 감사하게도 크래프톤 정글 6기 과정을 시작하게 됐다. 이번 과정을 통해 얻고 싶은 것은 다음과 같다.

- Algorithm, Data Structure, OS, Network, DB와 같은 핵심 CS 지식

- 하루 12시간 이상 주 6일 꾸준히 공부하는 습관

- 앞으로의 개발 인생에서 서로 믿고 의지할 수 있는 동료

 

임하고 싶은 자세

  목표로 하는 것을 얻기 위해선 정말 많은 노력이 필요하다. 배울 것은 산더미고 아무리 공부를 많이 한다고 한들 주어진 시간은 충분하지 않다. 그렇다고 포기할 수는 없다. 목표를 크게 가져야 그 일부라도 달성한다. 또 아무리 거대한 목표라도 그것을 최대한 잘게 sub goals로 쪼개고, 그것을 달성하는데 하루하루 집중하다 보면 어느새 수많은 계단을 올라와 있을거라 믿는다.

 

  공부에는 끝이 없다. 마라톤을 스프린트로 뛰면 결코 완주할 수 없다. 5개월의 정글 과정 중에도, 끝난 후에도 꾸준히 하기 위한 시간 관리와 체력 안배 또한 매우 중요하다. 공부만큼 휴식과 운동 또한 잘 챙겨보는 것이 목표다. 강렬한 빛을 내지만 짧게 끝나고 마는 초신성보다, 밝기는 상대적으로 약할 수 있어도 끊임없이 빛나는 항성이 되고 싶다.

 

정글이 끝난 후 나의 모습

  본 과정이 끝난 후 원하는 모습은 간단하다. 위에서 언급한 5개월 동안 얻어가고 싶은 것을 모두 가진 모습이다. 본 과정이 내 모든 문제를 해결해줄거라 기대 하지 않는다. 적어도 이 곳에서의 목표는 모두 이루고, 그것을 양분 삼아 더 빠르게, 더 오래 달릴 수 있는 기초체력이 완성되기를 바란다. 과정 이후로도 만들고 싶은 프로덕트를 만들며, 이를 바탕으로 나를 다음 단계로 성장시킬 수 있는 조직에서 내 몫의 역할을 하며 사회에 기여하겠다.

 

 

 

유튜브 영상 controller는 약 3초 동안 사용자의 움직임이 없으면 영상 controller를 숨김.

이를 react hook으로 간단히 만들어 봄

 

import { useEffect, useRef, useState } from 'react';

export default function useVideoControllers(playing: boolean) {
  const [showControllers, setShowControllers] = useState(true);

  const timeout = useRef<number | null>();

  useEffect(() => {
    const showControllers = () => {
      setShowControllers(true);
      if (timeout.current) window.clearTimeout(timeout.current);
      timeout.current = window.setTimeout(() => {
        setShowControllers(false);
      }, 3500);
    };
    window.addEventListener('mousemove', showControllers);
    return () => window.removeEventListener('mousemove', showControllers);
  }, []);

  return { showControllers };
}

 

알게된 것

  • state가 바뀌면 그냥 local 변수는 값의 재할당이 일어난다
    • re-render와 상관없이 data를 유지하고 싶으면 ref를 꼭 쓰자!!! useRef 쓸 일이 생각보다 정말 많네
  • 등록한 setTimeout은 clearTimeout으로 없앨 수 있다
  • setTimeout의 return 값은 number 형식의 id 이다

문제 상황

회사 일로 react-sortable-tree를 쓰는데, 'Cannot have two HTML5 backends at the same time.'라는 에러가 떴음

문제는 말 내가 한 페이지 내에서 두개 이상의 SortableTree를 사용하기 때문이었음

https://github.com/frontend-collective/react-sortable-tree/issues/177

해결 시도

찾아보니, SortableTreeWithoutDndContext를 쓰고, dnd를 내 컴포넌트에서 주입해주면 된다고 함. 

https://github.com/frontend-collective/react-sortable-tree/issues/511

그렇게 했지만, 렌더는 잘됐던게 아무것도 안뜸. 서치를 더 해보니 밖에서 주입해야하는 dnd가 적용이 안되서 그럼. 분명 안될리가 없는데 안됐음

 

해결

이슈를 계속 뒤적여보니, react-dnd가 내 package와 sortableTree 두 군데서 따로 load되어 사용되기 때문이라는 코멘트가 보였음

나를 살린 한 문장

https://github.com/frontend-collective/react-sortable-tree/issues/665

그래서 npm dedupe --legacy-peer-deps를 적용하니 문제가 해결됨!!

 

npm dedupe

여러 패키지에서 공통으로 사용하는 패키지를 정리해줌

https://outofbedlam.gitbooks.io/npm-handbook/content/cli/npm-dedupe.html

Next.js에서 window 등 client 객체 사용하기

  • Next.js는 기본적으로 SSR임
  • 따라서 평소처럼 window, document 등 client에서 쓰는 객체를 평범하게 사용하려고 하면 반드시 error가 남
  • 위와 같은 객체들은 꼭 useEffect를 통해 mount 되고 사용하는 것을 추천함

Next.js에서 window 객체를 사용해 화면 크기를 구하는 hook 예제

https://stackoverflow.com/questions/63406435/how-to-detect-window-size-in-next-js-ssr-using-react-hook

 

How to detect window size in Next.js SSR using react hook?

I am building an app using Next.js and react-dates. I have two component DateRangePicker component and DayPickerRangeController component. I want to render DateRangePicker when the window's width is

stackoverflow.com

 

tailwind css의 mobile first

  • tailwind는 mobile first임
  • 따라서 반응형으로 스타일링을 할 때, mobile을 default로 하고, pc를 옵션으로 설정해야 함(mobile을 타겟으로 하는 것들 sm:...등은 사용하지 않아야 함

https://tailwindcss.com/docs/responsive-design#mobile-first

 

Responsive Design - Tailwind CSS

Using responsive utility variants to build adaptive user interfaces.

tailwindcss.com

 

1. 좋은 개발자, 좋은 개발 팀이 되기 위한 조언

1) 남을 가르치는 기회를 가져보라 - 내부 컨퍼런스 등

  • 남을 가르치려면 내가 알고 있는 정보 정리를 잘 해야 함
  • 교육을 준비할 때 내가 무엇을 알고 모르는지 정확히 알 수 있음

 

2) 코드리뷰를 하라

  • 하나의 기능을 구현하는 방법은 수백가지임
  • 반면 한 명의 개발자가 생각해낼 수 있는 방법은 소수에 불과함
  • 코드리뷰를 통해 다른 사람의 코드를 참고하고 서로 대화하면, 최적의 구현법을 찾는데 매우 큰 도움이 됨
  • 코드리뷰 프로세스는 개발자 개인의 성장을 위해 매우 필요함
  • 하지만, 코드리뷰가 자리 잡기 위해선 조직적인 합의가 필수임
  • 리뷰 초반에는, 아무리 바쁘더라도 퇴근 전 하루 한 번은 꼭 코드리뷰 하는 것을 추천함

 

3) 테스트 코드를 작성하라

  • 테스트 코드는 경제적임
  • 서비스 / 비즈니스에 따라 적절한 테스트 커버리지가 다름
  • 테스트 코드는 새로운 개발자 landing하는 데에도 좋음

 

4) Software Architecture 문서를 작성하라

  • 비즈니스 / 팀의 상황과 특성에 따라 중요한 특성(Quality Attribute)이 다름
  • Software Architecture 문서는 Quality Attribute 등 “개발 철학”을 정의한 문서임

(Software architecture in practice 책 추천)

 

 

5) 개발 스터디를 하라

  • 공부에는 강제성과 관성이 필요함
  • 혼자하는 공부는 위 두 요소를 충족시키기 어려움 → 지속하기 힘듦
  • 29살 때는 2주 간격의 스터디를 6개 정도 진행함
  • 지금까지도 개발 스터디 하는 중. 아래의 책으로 진행하고 있음

 

6) 문서 작성 또한 중요하다

  • 최상의 엔지니어는 스펙을 정의하고 정리하는 사람임
  • Use Case Specification 문서 정도는 만들어 보는 것을 추천함

 

7) 해외 개발 컨퍼런스에 참가하라

  • 해외 컨퍼런스에는, 유명한 언어 / 프레임 워크의 창시자들을 직접 만나고 질문할 수 있음
  • 그러기 위해 영어공부는 매우 필수임!

 

8) 이슈 트래킹 툴 도입 추천

  • 숫자로 이슈와 관련된 내용들을 트래킹 하는 것이 중요함
  • 개발 조직이 크기 위해 체계와 체계를 실천하기 위한 이슈 트래킹 툴과 같은 도구가 필요함

 

2. Q&A

Q. CS 지식은 언제, 어떻게 공부하는 것이 좋은가?

A. 필요할 때 공부하는게 제일 좋다. 공부한 내용을 체화하려면 피부에 와닿는 현실에서의 이슈가 필요하다

 

Q. 좋은 코드, 좋은 개발자란?

A. 아래와 같이 생각한다

  • 좋은 코드 - simple & solid한 코드. 오랜 세월 계속 사용할 수 있는, 높은 커버리지, 유연함 등
  • 좋은 개발자 - 편견이 없는 유연한 개발자. 다양한 언어 / 소프트웨어의 철학을 이해하고 적절히 조합하여 사용할 수 있는 개발자

 

3. 기타

  • 추천하는 책 목록
    • Design Pattern
    • Refactoring
    • Optimal Java
    • Clean Architecture
  • 성장하지 못하는 개발자들은 난관에 부딪혔을 때 고민 없이 바로 물어봄
    • 훌륭한 개발자가 되기 위해선, 충분히 혼자 고민을 해야 함
    • 고민을 바탕으로 자신만의 질문을 정교화하고, 그 질문에 대한 자신만의 가설 or 결론을 세워야 함
    • 그 뒤에 질문을 해야 함
  • 2030 개발자들에게 꼭 추천하는 것!
    • 연애를 하세요… (40대 이상의 개발 독거노인들 많다..)
    • 영어공부 열심히 하세요
    • 계속 꾸준히 공부하세요. 혼자 힘들면 스터디를 하세요

 

1. input에서 한 글자 입력 후 focus를 잃는 현상

react로 input을 사용하다보면, 가끔 한 글자 입력 후 input의 focus가 사라지는 현상이 발생한다.

이러한 현상의 원인은 100% state의 변경 등으로 인해 해당 Input이 re-render 되기 때문이다

 

State 변경으로 인한 re-render

1. input만 함수 or 컴포넌트로 따로 묶는 경우

export default function Editor() {
	
	const [name, setName] = useState("");
    
    const onChange = (e) => {
    	const {value} = e.target;
        setName(value);
    }
    
    const Input = () => (<input name="name" value={name} onChange={onChange} />)

	// 한 글자 입력할 때마다 state가 변경 -> Input 컴포넌트가 re-render됨 -> focus 잃음
    // input을 아래 return에 바로 넣어줘야 함
	return (
    	<div>
        	<Input/>
        </div>
    )
}

https://stackoverflow.com/questions/42573017/in-react-es6-why-does-the-input-field-lose-focus-after-typing-a-character

 

In React ES6, why does the input field lose focus after typing a character?

In my component below, the input field loses focus after typing a character. While using Chrome's Inspector, it looks like the whole form is being re-rendered instead of just the value attribute of...

stackoverflow.com

 

2. map의 key 값에 함수 값을 주는 경우

key 값으로 nanoid() 등을 주는 경우, state가 변경될 때마다 nanoid()가 새롭게 실행되어 input이 새롭게 re-render 됨 → focus 잃음

 

3. input이 있는 styled-component 객체를 jsx 컴포넌트 안에 선언하는 경우

state가 변경될 때마다 styled-component 변수를 새롭게 선언함 → focus 잃음

https://www.inflearn.com/questions/121968

 

input 한글자 입력후 focus사라지는 현상 - 인프런 | 질문 & 답변

어...아래 에러는 해결했는데  로그인할때 input창에서 한글자 입력하면 focus를 잃어서 다시 입력하려면 input창을 클릭해야하는 현상이 발생하는데  이건 어디서 문제가 발생한 걸까요 제가 보이

www.inflearn.com

 

2. string으로 js object 값에 접근하기 - reduce 사용

const obj = {
  lego: {
    name: "hello",
  },
};

const string = "lego.name";
const result = string.split(".").reduce((acc, cur) => acc[cur], obj); // hello

 

1. 브라우져별 지원하는 동영상 format이 다를 수 있다

  • 아이폰으로 촬영된 영상의 포맷은 HEVC임
  • 하지만 해당 포맷은 크롬에서 지원하지 않기 때문에 재생이 안됨

1. react-query 특정 조건일 때 fetch하도록 하기

  • 이전부터 찾아 해매던 기능... 역시 영어로 stack overflow 보는게 최고 빠르다...
  • document 예제와 같이, query option으로 enabled(boolean) 값을 주면 됨!! 
    • enabled로 준 값이 true일 때만 fetch함
    •  // Get the user
       const { data: user } = useQuery(['user', email], getUserByEmail)
       
       const userId = user?.id
       
       // Then get the user's projects
       const { isIdle, data: projects } = useQuery(
         ['projects', userId],
         getProjectsByUser,
         {
           // The query will not execute until the userId exists
           enabled: !!userId,
         }
       )
       
       // isIdle will be `true` until `enabled` is true and the query begins to fetch.
       // It will then go to the `isLoading` stage and hopefully the `isSuccess` stage :)

https://react-query.tanstack.com/guides/dependent-queries

 

Dependent Queries

Subscribe to our newsletter The latest TanStack news, articles, and resources, sent to your inbox.

react-query.tanstack.com

https://stackoverflow.com/questions/63397534/conditionally-calling-an-api-using-react-query-hook

 

Conditionally calling an API using React-Query hook

I am using react-query to make API calls, and in this problem case I want to only call the API if certain conditions are met. I have an input box where users enter a search query. When the input va...

stackoverflow.com

 

1. PM을 내려놓으며 배운 것들

회사에서 일을 하면서 대표님과의 의견 충돌로 맡고 있던 프로젝트의 PM을 내려놓게 됐다.

위 과정에서 배운 것들을 간단히 정리해보자.

  • 사람은 결국 따라와주길 바라는 자기만의 규칙이 있다
    • 아무리 상대가 규칙이 없이 자유롭게 해봐라 해도, 사람인 이상 따라줬으면 하는 규칙이 분명 있다
    • 그러니 정말 자유롭게 했을 때 상대가 뭐라고 해도 속상해하지 말자. 사람인 이상 어쩔 수 없다
    • 그 규칙을 어떻게하면 귀찮게 안하면서 잘 파악할 수 있을지 고민해보자
  • 그릇이 큰 사람이 되자
    • 상대가 나의 기분을 상하게 했더라도, 나도 똑같이 나가며 들이받지 말자(정말 부당하고 나쁜 일 제외)
    • 들이받을 당시에는 통쾌할 수 있으나, 나중에 분명 후회한다
    • 상대의 잘못을 지적하거나 따지려 하지 말고, 나의 부족한 점에 집중하자
    • 상대방을 바꾸려 하지 말고, 내가 스스로를 바꿀 수 있는 것에 집중하자
    • 상대가 어떠한 자세로 나오든, 나는 끊임 없이 낮은 자세로 상대방을 대하자
  • 일과 나를 동치시키지 말자
    • 사회에서 그룹으로 하는 모든 일은, 분명 내 마음대로 안되고 좌절하게 된다
    • 일과 나를 동치시킨다면, 그때마다 상처입고 괴로운 시간을 보내게 된다
    • 하지만 이런 결과가 일을 더욱 잘하게 되는데 큰 도움은 되지 않는 것 같다
    • 오히려 일과 나를 분리시키고, 객관적인 관점에서 일을 잘되게 하는데 집중하는게 더욱 도움이 많이 되는 듯 하다
  • 사람을 그 사람이 한 말이 아니라, 그 사람이 한 행동으로 이해하자
    • 말과 행동이 일치하는 것은 정말 어렵고, 나도 잘 지키지 못한다
    • 하지만 이 어려운 것을 상대방이 지킬 것이라 생각하고, 말로 그 사람을 이해한다면 충돌하는 행동들에 상처받고 이해하지 못하게 된다
    • 말에 현혹되지 말고 그 사람의 행동으로 이해하자
  • 회사 분의 말씀 중 가장 위로가 되었던 말
    • "저는 어떤 일이 잘못되었을 때, 개인이 아니라 팀 전체의 문제라고 생각해요. 누군가 개인을 탓한다면 그 탓하는 사람이 부족한 것 같아요. 개인을 탓한다고 변하는건 없어요. 무슨 일이 잘못된다면, 그것을 예방할 수 있는 시스템을 고민하고 개선하는게 맞아요"
      • 내가 자책하고 다른 사람들이 나를 부족한 사람이라 여길 것이라 생각했던건, 어찌보면 나 스스로가 회사에서 문제가 생긴다면 문제를 일으키는 개인을 탓하는 마음을 갖고 있어 그런 것 같다. 
      • 나부터 개인을 탓하는 마음을 가지지 않도록 그릇을 키워야겠다

 

1. Custom Hook 사용 조건

  • Rules of Hooks를 지켜야 함
  • 다른 컴포넌트에서 hook을 동시에 여러군데서 사용해도 side effect가 없어야 함
  • 디버깅하기 용이해야 함

https://medium.com/finda-tech/%ED%95%80%EB%8B%A4%EC%97%90%EC%84%9C-%EC%93%B0%EB%8A%94-react-custom-hooks-1a732ce949a5

 

핀다에서 쓰는 React Custom Hooks

+ Custom Hooks로 적합한 것과 그렇지 않은 것

medium.com

 

2. React: Too many re-renders Error

  • setState 함수가 react component function에서 useEffect나 closure로 감싸져 있지 않아서 생기는 문제
  • 컴포넌트 render → setState 초기화 → 컴포넌트 render → setState 초기화 → so on....

 

+ Recent posts