react 브랜치 커밋 (2018 04 18)

원래 개발일지 1에서 Blaze쓰고싶다고 했었는데….. Blaze를 쓰다가 짜증나서 React를 대충 훑어봤더니 솔직히 이게 더 쉬운거같아서 다시 갈아타기로 했다.

React에 대한 리뷰도 곧 있을 듯. 일단은 좀 써보다가 익숙해지면 올리려고 한다. 확실한건 Blaze보다는 빠르고, 내가 느끼기에는 React 사용법이 좀 더 명확하고 편한 것 같다. Blaze는 뭔가 철학이 없는거같다..


그래서 React로 갈아타게 된 관계로 Blaze로 짜던 것을 버리게 될 것 같은데, 깔끔하게 처리하기 위해서 새로운 git branch를 팠다. pebble-demo의 React 브랜치에서 확인할 수 있다. 이제 git에 대한 설명도 올려야되는데… 그건 시험끝나고 하도록 하자. Blaze에서 구현한 기능을 다 구현하고 나면 master에 merge할 생각이다.


아무튼, Blaze로 한 것들을 그냥 다시 만들고 있다.

/imports/ui/Stream/Stream.jsx

공식 튜토리얼에서는 mongo collection하고 연동하기 위해서 withTracker라는 것을 썼다. (react-meteor-data라는 npm 패키지를 추가적으로 설치해주어야 한다.)

근데 withTracker는 React에 찾아도 안나오고 meteor에서도 잘 안보이길래, 그냥 getPosts() 메소드를 Stream 클래스 안에 만들어서 collection하고 연동시킬려고 했는데, 안되더라. 업데이트만 안되는게 아니라 그냥 collection을 찾지도 못했음. 왜안되는지는 잘 모르겠다. (왠지 안되는게 맞는거같기도 하고…)

그래서 결론은 React에 collection을 실시간으로 연동시키려면 withTracker를 사용해야 한다는 것이다.

내가 쓴 withTracker 코드는 다음과 같다.

export default withTracker(() => {
   return {
     posts: postColl.find({}, { sort: { createdAt: -1 } }).fetch()
   };
})(Stream);
대충 해석하면, { post: … } 객체를 계속 갱신해서 Stream 컴포넌트에 props로 넣어 주겠다는 뜻이다. 그리고 export하는 것은 props가 갱신되는 Stream 컴포넌트이다. 그래서 실시간으로 업데이트되는 모습을 볼 수 있다. 자세한 동작방식은 기회가 되면 찾아봐야겠다. 일단 그나마 잘 나와있는 링크.

post 입력 폼을 만들기 위해서 Quill이라는 에디터를 사용했다. 깔끔하기도 하고, Doc도 잘 되어 있어 사용하기 편한 것 같다. 그리고 꽤 많이 사용하는지, react용 quill도 나와 있다. 그냥 <span style="font-size: 10pt;">meteor npm install --save react-quill</span>해서 설치하면 바로 사용할 수 있더라. (물론 이젠 package.json에 등록되어있기 때문에 github에서 클론해서 쓰는 사람은 meteor npm init만 하면 자동으로 다 깔린다.)

입력 폼은 /imports/ui/Stream/PostForm.jsx에 따로 컴포넌트를 만들었다. React 문서, react-quill 리드미를 참고하면 할 만 하다.

아직은 format같은걸 안들여온다. 그러니까 post를 만들 때는 볼드나 이탤릭같은 것을 할 수 있지만, content에는 그 정보가 들어가지 않는다. getText()로 가져와서 그러한데, 나중에 content는 format을 가져오고 summary는 content 앞부분 조금을 format없이 가져오는 것으로 해야될 것 같다.

일단 조만간은 plain text만 사용할 듯.


코드를 깔끔하게 동작하도록 만들면서 찾아본 점이 꽤 있지만, 다 적기에는 너무 사소한 듯 해서 조금만 적어보도록 하자.

  • react component의 state는 자기 자신만 바꿀 수 있다. 자식의 state를 부모에서 바꾸려고 하지 말자.
  • a 태그(하이퍼링크)에 onClick 속성으로 주어지는 함수에서, preventDefault를 하면 앵커 태그가 링크로서는 작동하지 않는다. Stream/Post.jsx (line 13)에서 사용했는데, 지우기를 눌렀을 때 화면을 안움직이게 하기 위해서이다.
  • materilize 를 위한 class는 태그에 상관없다. Steram/PostForm.jsx (line 50)에서 사용했다. 예를 들어, 원래 a 태그에 들어가는 btn waves-effect 같은 속성들도 button 태그에 쓸 수 있는 것이다. 자세히는 모르겠지만, 외형은 일단 동일한 것 같다.
  • react component가 render하는 JSX에 리스트가 들어갈 수도 있다. (Stream/Stream.jsx line 28) 이때는 각 태그에 props.key (line 12)을 명시적으로 부여하라고 react가 주장한다. 그래서 collection 내부의 _id를 줬는데, 그게 좋은 선택인지는 잘 모르겠다.
  • react component의 props들 중에서 onClick등에 함수가 필요한 경우가 있다. 이 때는 스코핑을 위해서 .bind(this)를 해주어야 하는 경우가 있는데, 이 작업은 constructor에서 하라고 한다. (Stream/Post.jsx line 9, 33)
  • react component에서 자신이 render하는 element들 중에서 편집해야 하는 노드가 생길수도 있다. (Stream/PostForm.jsx line 10~, 40~) 이 때는 ref라는 속성을 사용하는데, 자세한 동작 메커니즘은 잘 모르겠으나, 일단 line 10, 11처럼 쓰고 있다. 자세한 사용방법은 react 공식 문서에 있긴 하다.
  • /client/main.html에서 위에 있는 링크 / 스크립트들을 없애면 materialize나 Quill이 제대로 동작하지 않는다. 헤더같은 거라고 보면 될 듯 하다.