## [J03] 7주차 피어세션
## 구성원
J158_이정준, J011_권재호, J075_문상혁, J170_이호현, J218_홍승용, J114_신정원, J145_이신필
### 이야기 해볼 주제
1. `requestAnimationFrame`
- 1초에 60하는 것을 보고 게임을 개발하는 것으로 생각하고 개발했다.
- 리액트 말고 상태관리할게 하나 더 생겨서 차원이 하나 더 생긴 느낌.
2. Socket Multiplexing - namespace
- 한사람당 소켓을 여러개 만들어 할려고 했는데 네임스페이스로 멀티플렉싱이 가능하다.
- 서버 하나가 굉장히 많은 유저를 수용하고 유저 한명당 여러개의 포트를 사용할 경우 포트가 부족할 수 있는데 멀티플렉싱으로 이걸 해결할 수 있다.
- (서버) 리눅스에서 한 프로세스당 열 수 있는 파일 디스크립터개수가 제한되어있습니다. 기본 설정 1024개 이 이상 열시 too many open files 에러가 발생하며, 설정을 통해서 늘릴 수 있습니다. 그리고 (클라이언트) 에서 열수 있는 포트의 개수가 10000~64000개 사이 최대로 열수있기 때문에 최대 열수있는 ws 약 50000개 정도의 동시 접속이 됩니다.
- [OS 레벨 소켓 이야기](https://socket.io/docs/v4/performance-tuning/#at-the-os-level)
3. React hooks (`useState`, `useEffect`, `useRef` 등)
- useState
1. 상태 생성 setState((prev) => prev + 1)
2. 비동기로 동작
3. [].push 금지
4. shallow 비교하기때문에 객체가 변하지않으면 리액트는 스테이트 변화를 감지를 못함.
5. addEventListener와 같은 것으로 state를 처리하면 배치처리가 되지않는다.
6. 외부에서 하더라도 배치에 업데이트를 하고싶다면 unstable_batchedUpdates함수를 이용해서 할 수 있다.
7. 상태값을 객체로 관리할때는 useReducer가 더 좋다.
``` js
function onClick() {
ReactDOM.unstable_bachedUpdates(() => {
setCount(prev => prev+1);
setCount(prev => prev+1);
});
}
```
- useEffect - 의존성 배열 적는게 익숙하지 않는다.
- useRef - 돔 잡는 거 말고, 이전 스테이트를 저장할 때, 값이 변해도 컴포넌트 리렌더링을 하지않는다.
- 계속 변화하는 대상을 기억하기 위해 useRef 사용
- useCallback - 컴포넌트 렌더링이 일어나면 함수를 새로 만드는데 내부 변수로만 사용하는 순수함수라면 새로 만들지 않아도 되기때문에 사용하면 좋다.
- useMemo - 함수의 결과 값을 만들어 두고 저장하고 재사용
- 인자를 함수로 받고 결과값을 저장한다!
- 안 변하는 결과를 저장
- ex) 소켓을 생성하는 함수를 넣어두면 생성된 소켓을 새로 만들지 않고 사용된다.
- useContext
- 데이터를 전달해줄 하위 컴포넌트가 상위 컴포넌트에서 상당히 멀리 떨어져 있는 경우
- 원래같으면 props로 계속 내려줘야 하고, 중간 컴포넌트들은 그 값을 쓰지 않아도 일단 받고 물려줘야 하는 문제가 있음.
- Provider, Consumer로 이루어짐.
- Consumer 컴포넌트는 데이터를 찾기 위해 상위로 올라가며 가장 가까운 Provider 컴포넌트를 찾는다.
- Provider 컴포넌트의 속성값이 변경되면 하위의 모든 Consumer 컴포넌트는 다시 렌더링된다.
- 중간에 위치한 컴포넌트의 렌더링 여부와는 상관 없다
- `useMemo` 등을 통해 렌더링을 막은 컴포넌트가 위에 있어도 Consumer 컴포넌트들은 전부 다시 렌더링된다.
- `useMemo` 를 쓰고, 속성값이 없는 컴포넌트는 최초에 한번만 렌더링되고 이후 변경되지 않는다.
- 데이터의 종류별로 Context를 만들어서 사용하면 렌더링 성능 상 이점이 있다.
- setState 함수를 넘겨 context 데이터를 원하는 곳에서 변경하도록 할 수도 있다.
4. global state 관리
- ContextAPI의 최상단에 올려서 사용하고 있습니다.
- Redux는 생각보다 쓸일이 없었습니다.
- Recoil 물건입니다.
- 추상화의 끝판왕 useState와 비슷한 하게 사용하고 파생시킨 라이브러리 == selector가 있다.
5. 커스텀 훅
- 로직이 길어진다 싶으면 분리 혹은 재사용 될것같으면 분리
- hook은 호출하는게 중요하지 선언되는게 중요한게 아니라서 외부에 생성하고 호출하여 사용한다.
- ex) 케릭터 이동 state와 useEffect로 초기화 이런 것들을 묶어서 사용할 때 사용
- 커스텀 훅 네이밍 컨밴션 : `use...` eslint가 잡아줘요!
6. 프론트 alias
- @craco/craco, craco-alias install 해서 해결했습니다.
7. 협업 방식
- github을 최대한 활용했습니다. issue, pr template 등
- kakao talk driven development
8. 리렌더링
- 퍼포먼스탭을 보고 확인하자.
### 질문
1. 맵이동 하신분들 어떤식으로 하셨는지 궁금합니다
- 사용자 키보드 인풋(방향 정보)에 따라 맵이 이동하도록 구현했습니다. (캐릭터는 항상 맵의 중앙에 위치하도록 고정한 상태에서)
- 사용자 캐릭터 위치를 저장하고 키보드 입력에 따라서 x, y를 변경시켜주었습니다. 그러고 변경된 위치에 따라서 맵의 일부분을 다시 canvas로 그려주는 식으로 구현했습니다
- 맵은 고정시키고 캐릭터랑 뷰포트만 바꿔줘서 캐릭터가 고정되어있는것 같은 효과를 줬습니다. 근데 깜빡거림은 해결이 안되네요...
- Layer를 나눠서 맵에 그려넣는 방법...
2. 리뷰받은 것 중에 공유하고 싶은 내용 있나요?
- 리뷰를 아직 못받았어요..
- import문을 작성하는 순서도 컨벤션으로 정하기도 하나봅니다. 리뷰어님은 알파벳 순서로 상위 디렉터리가 같은 거 끼리 붙여쓰고 다르면 한 줄씩 띄어서 사용하고 있다고 합니다.
=> 오..저는 실제라이브러리 -> 본인이 만든 라이브러리 순으로 임포트하는거만 생각했는데 저렇게도 하시는군요
- canvas에서 canvas 컴포넌트가 렌더링이 될 필요가 없으므로 useState로 사용자의 상태를 관리할 필요가 없었습니다.
3. 리액트 프로젝트 구조 다들 어떻게 짜셨는지 궁금합니다.
- 음.. 화면공유하고 보여드리는게 좋겠네요!
4. 프론트를 CRA로 했는지 webpack으로 custom 설정했나요?
- 저희는 cra로 만들고 craco로 alias만 설정하여 사용했습니다.
- CRA로 만들고 eslint랑 prettier만 따로 설정해뒀습니다.
5. 다중 사용자 이동 렌더링 어떤식으로 진행하실껀가요?
- 다른 사용자들을 렌더링시키는 canvas 레이어를 하나 따로 뒀습니다. 물론 아직 구현은 안했습니다하핳ㅎㅎ
- 모든 사용자의 위치정보를 갖는 state를 map object로 관리하고 map object가 바뀔때마다 리렌더링할 생각이었습니다.
- 그렇다면 서버에서 사용자들의 위치 정보를 어떻게 보내주는게 좋을까요?
6. 캐릭터 커스텀 여부 && 구현 방법
- 걷는 모션은 구현 못하고 방향 바뀌는것만 되게 했습니다.
- 저도 걷는 모션은 하지못했어요.. 너무 어려워요 애니메이션! 안해봐서 그런건가..
- 유저의 걷는 방향이 키보드 인풋에 의해 지정이 되면 걷는 모션을 위해 왼쪽 팔이 움직이는 프레임, 정자세 프레임, 오른쪽 팔을 움직이는 프레임 순으로 계속 반복해서 캐릭터를 그려주어서 에니메이션 모션을 구현했습니다.
- [유용 래퍼런스 공유](https://dev.to/martyhimmel/moving-a-sprite-sheet-character-with-javascript-3adg)
7. 여러개의 context를 제공할 때, 여러개의 태그를 사용하는 방법밖에 없을까요?
- 안쓰려면 결국 redux, recoil 등 라이브러리를 사용해야 할 것 같아요.
- wrapper로 묶는 방법 좋은것 같습니다.
8. 브랜치 관리 다들 어떻게 하시나요?
- 한명이 포크해온걸 같이쓰고, dev 브랜치, feature 브랜치를 나눠서 작업한 후에 dev로 머지시켜서 upstream으로 PR을 날립니다.
- 저희도 상당히 비슷하네요. 저희는 dev로 머지전에 한번더 회의하고 같이 회의하는 과정이있어요
- 거창하게 이야기하면 github flow입니다.
9. styled components 범벅 해결 방안?
- styled(StyledComponent)`` 이미 만들어진 것들을 활용하는 방법
- & 를 통해서 내부의 차일드에 접근해서 스타일을 주는 방법
- & > tag[attribute]
- nth-of-type(1)
- 간단한 것들은 inline-style 해도 될 것같아요.
10. 페어프로그래밍 다들 하셨나요?
- 한번쯤해보자, 재밌다
- vs code Live Share를 활용하면 좋습니다.
- 페어 프로그래밍을 거의 하지 않았는데 live share 기능을 이용해서 했더라면 더 좋았겠다고 생각이 드네요.