byyoungjin / myblog-next

https://log.byyoung.me
0 stars 1 forks source link

[MY-5]Front 작업 #7

Closed byyoungjin closed 3 years ago

byyoungjin commented 3 years ago
byyoungjin commented 3 years ago

topic_1 : theming & reusable css with scss

absoulte import with scss

css - How to use absolute path to import custom scss, when using react + webpack? - Stack Overflow

Basic Features: Built-in CSS Support | Next.js

나는 src/styles 구조이므로

  const sassOptions = {
    includePaths: [path.join(__dirname, '/src/styles')],
  };

reusable

https://blog.logrocket.com/how-to-write-reusable-css-with-sass/

byyoungjin commented 3 years ago

issue_1 .

SSR draft.js 에러 https://github.com/facebook/draft-js/issues/2332

byyoungjin commented 3 years ago

issue_2 : build error

원인 : switch 문에서 default 에 그냥 return 해서 {} 가 반환되지 않아서 생긴 오류

 switch (phase) {
    case PHASE_DEVELOPMENT_SERVER:
      env = {};
      break;
    default:
      return  // 삭제함 
  }
byyoungjin commented 3 years ago

딴짓

byyoungjin commented 3 years ago

issue backlog

byyoungjin commented 3 years ago

backlog

byyoungjin commented 3 years ago

sidebar 위치문제

https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

getBoundingClientRect 는 Viewport 에 대한 top, left 값을 준다. 그래서 scroll 이 변해도 viewport 에 대한 상대값을 주기때문에, 내가 사용하는 조건을 적용하려면 스크롤 값을 더 더해줘야한다. 기존에 (top + window.scrollY) 를 적용하여 해결!

 if (blockNode) {
        const blockNodeRect = blockNode.getBoundingClientRect();
        const { x, top } = blockNodeRect;
        setTop(top + window.scrollY);
        setLeft(x);
        setScale(1);
      }
byyoungjin commented 3 years ago

image 넣은 뒤 read only 현상

Unsplash image block 에 초기 useEffect 로 readonly 설정하는 로직이 있었다. input 에만 적용되어야 하는데, image 블록이 넣어진 뒤에도 적용되고 있어서 생기는 문제, image 블록이 들어간뒤에는 readOnly 로 설정하지 않도록 바꿔서 해결!

  useEffect(() => {
    if (!unsplashImageInfo) {
      setIsEditorReadOnly(true);
      if (searchInputRef && searchInputRef.current) {
        searchInputRef.current.focus();
      }
    }
  }, []);
byyoungjin commented 3 years ago

딴짓

typescript 좋은 소스 https://typescript-kr.github.io/

byyoungjin commented 3 years ago

next js 에서 font 넣기

https://kirazhang.com/posts/nextjs-custom-fonts

byyoungjin commented 3 years ago

upper bar 설정하기

issue

byyoungjin commented 3 years ago

issue : next.js 에서 draft.js decorator가 작동하지 않음 .

원인은 EditorState.createEmpty() 할때 decorator 를 전달해주지 않아서. createEmpty(decorator) 를 하니까 제대로 적용됨.

결론. 위 createEmpty(decorator) 의 decorator 만 적용이 되고 내가 만든 customPlugin 안에 decorator, 분명 decorator 를 쓸수있다고하는데 decoartor 를쓰는 plugin 들의 decorator 는 적용이 되지 않았다. linkyfy 를 써봤는데, 적용이 되지 않음 이유는??

조금더 알아봐야겠지만 Draft.js 의 Editor 에서도 decorator prop 은 없다. Editor.createEmpty(decorator) 형식으로 decorator 를 적용한다.

따라서 위 방식으로만 적용하도록 하고, decorator prop이나, custom plugin 상에서 decorator 는 사용하지 말자.

decorator 를 사용하는 plugin 들이 어떻게 적용되는지 알아보자

byyoungjin commented 3 years ago

블록스타일 손보기

byyoungjin commented 3 years ago

issue : react-spring , leave 애니메이션 적용안됨

관련이슈 https://stackoverflow.com/questions/56169228/react-spring-transition-leave-animation-not-working

해결 :

위와 비슷하게 자식컴포넌트 관계를 없애고, useTransition 을 부모 로 옮겨오니 제대로 작동. 아마도 rendering 되는 과정에서 useTransition 자체가 drop 되어버려서 leave 애니메이션이 작동하지 않은것 같다.

export const useModal = () => {
  const [showModal, setShowModal] = useState(false);
  const [isBrowser, setIsBrowser] = useState(false);

  const transitions = useTransition(showModal, {
    from: { transform: 'translateY(100%)' },
    enter: { transform: 'translateY(0%)' },
    leave: { transform: 'translate(100%)' },
  });

  useEffect(() => {
    setIsBrowser(true);
  }, []);

  const Modal = ({ children }: { children: React.ReactNode }) => {
    if (isBrowser) {
      return ReactDOM.createPortal(
        transitions((transitionStyles, item) =>
          item ? (
            <animated.div
              className={styles.modalOverlay}
              style={transitionStyles}
            >
              {children}
            </animated.div>
          ) : (
            ''
          )
        ),
        document.getElementById('modal-root')!
      );
    } else {
      return null;
    }
  };

  return { Modal, setShowModal };
};
byyoungjin commented 3 years ago

state management without redux

기존에 나는 redux, redux-saga 를 활발하게 썼는데

  1. 모든 state 를 하나의 store 에 넣음으로써, state 관리가 용이했다. (확실한 규칙)
  2. redux-saga 를 이용해서 async 한 로직들을 관리하기 편했다.

그럼에도 불구하고 모든 state 를 하나의 store 에 넣고, dispatch 하는과정에서 불필요한 state 까지 store 에 넣는 경우도 생겼고, 너무 redux store 에만 의존하는것같아서 다른방식으로 한번 구현해보려고한다. redux store 와 saga 가 다소 무겁지 않나 해서 빼고 구현해보고 차이점을 보려고 한다.

하고자하는것은.

  1. 적절한 기준을 세워서 state 를 local 하게 나눈다.
  2. context API 와 hook 을 사용해 구현한다.
  3. 주의할 점과 차이점을 살펴본다.

1. 적절한기준을 세워 state 를 local 하게 나눈다.

이부분이 제일 어려운것 같은데, prop drilling 을 막으면서도,

  1. 특정 state 가 쓰이는 범위 최상단에 state 를 넣어야하고
  2. 전반적인 state 가 어떻게 관리되는지 알수있는 방법이 있어야한다. (어떻게 state 를 local 하게 나눴는지 규칙이 있어야 한다.)

예를들면 EditorState 는 editor 에, userState 는 앱 전반을 감싼다.

page 나 component 단에 들어가게되면 너무 불규칙하게 state 가 관리될것같아서 layout 에 들어가는게 가장 합리적이라고 생각한다. layout 자체가 어떤 비즈니스 로직에 맞춘 wrapper 를 넣는 것이고, layout 과 함께 state 를 넣어주는게 꽤 합리적인것같다. 그리고 "기본적으로 state 는 layout 에서 관리한다" 라는 규칙도 생긴다.

다만 layout 역시 각 page 를 감싸기때문에, 서로 다른 page 간의 routing 시, state 가 유지되진 않는다. 그래서 "page 간의 routing 에도 유지되야하는 state 는 _app.tsx 에서 관리한다." 라는 두번째 규칙을 만들 었다.

그래서 기준을 정리하자면

  1. "기본적으로 state 는 layout 에서 관리한다"
  2. "다만 page 간의 routing 에도 유지되야하는 state 는 _app.tsx 에서 관리한다."

2. context API 와 hook 을 이용해 구현한다.

https://medium.com/strands-tech-corner/react-state-management-without-redux-d39c7087039d

byyoungjin commented 3 years ago

Context api VS Redux

  1. Context Api 는 기본적으로 Rerender 한다. , prop drilling 은 prop 이 같으면 rerender 하지 않는다. Redux 도 마찬가지 기능을 제공한다.

  2. 과연 redux 대신 contextApi 를 쓰는게 올바른가? 오히려 rerender 때문에 안좋은점도 있다. 둘중에 하나만 쓴다는게 정답은 아니다. 둘을 같이 쓰는것도 방법이 될 수 있다.

  3. 모듈화 되길 원하는 component 가 있다면, redux 를 안넣는게 답일수 있다. 넣더라도 모듈화된 component 최상단에만 redux 의 state 를 전달하고, 이후에는 prop drilling 이나, context API 를 이용할 수있다.

  4. You mgiht not need Redux _dan ambramov 에 따르면 redux 를 씀으로써 얻을 수있는 이점들이 있고, 이게 필요하다면 쓰면되고, 아니라면 local state 로 처리하면 된다고 함. server side rendering 에서 persist state 처럼.. 전반적으로 redux 를 option 으로 끼고 가는 건 나쁘지 않은 선택인듯하다.

  5. server side rendering with nextjs & redux

중간 결론

redux 에서 제공하는 기능이 많고, saga 를 사용할 수있는점, 전반적으로 optimization 되어있다는점에서 redux 를 사용안할 이유는 없는것 같다. 다만 global 로 관리가 필요한 state 에 대해서만 적용해야 한다. redux-toolkit 이 괜찮아보인다 사용해보자

모듈화가 필요한 부분은 prop 을 drilling 하거나, context API , hooks 를 이용해서 구현해보자.

+ Next.js 에서 redux 사용

next.js 는 기본적으로 serverside 에서 fetching 해서 넘겨준다. redux 를 적용하려면 next-redux-wrapper 라이브러리 이용해서 server side 에서 initial prop 을 넘겨주는 방법을 사용해야한다.

이쯤에서 드는생각은 global state 가 진짜 필요한 경우가 있는가

  1. 일단 page 단위에서 hydrate 된 page 를 받은뒤 Rendering 관련된 state는 contextApi& hook 을 이용해도 될것 같다. 그냥 Prop 으로 넘겨도 될것같고.

  2. 페이지간 연결되는 global State 가 필요한 경우에도 Using react Context Api in nextjs 를 이용해서 구현하면 될것 같다.

  3. auth 의 경우엔, next-auth 라이브러리를 사용하면 global state 로 가져가야할 경우는 없다.

  4. saga 의 기능도 hook으로 충분히 구현이 가능하다.

결론

state 란 페이지에서 나타내는 정보 라고 볼수 있을것 같다. 그럼 페이지가 로드될때 fetch 해오면 되는데, next.js 에서는 server side 에서, spa 앱은 client 에서 fetch 한다. 그정보를 global 에 저장할 필요는 없을것 같고, scoped 해서 각 페이지별로 컨트롤 하도록 구현하면 될것 같다. reload 하더라도 state 가 저장되게 하려면, local storge 를 활용하면 될 것같다.

byyoungjin commented 3 years ago

1차 마무리

byyoungjin commented 3 years ago

issue 1: Auth sync 문제

초기로딩시 backend server 쪽 코드에서 user 가 authenticated 되어있지 않음. front 코드에서는 user 가 authenticated 되어있음

일단 Local 상황이고, delpoy 했을때 어떻게 바뀌는지 확인해볼 예정

1. build 해서 실행해봤더니,

profile, about 페이지들은 정상작동하고

post 관련페이지만 오류, ->리로딩시 auth context 를 가지고 오지 못하는 문제인듯하다. -> 일단 serverside prop 으로 auth 정보를 보내줘야할듯 하다. -> context 는 페이지 단위에서만 사용하고 페이지간에 공통 state 관리는 serverside 단에서 먼저 이뤄져야 할 듯하다.

byyoungjin commented 3 years ago

staged, production merging 작업

api index 를 지우고 생성하는것들이 있어서 바로는 안됨

1. graphql table 지우고 upload

-> auth 부분에서 오류 -> aws console 상에서 환경마다 통일하고 시도해보자.