[TIL] 0201

yoon Y·2022년 2월 3일
0

2022 - TIL

목록 보기
29/109

Like컴포넌트에 api호출, contextApi로직이 포함되어있어서 storyBook에 작성할 때 오류가 났다

page컴포넌트에서 호출한 후 props으로 내려줘야했는데 depth가 너무 깊고, 2개의 page에서 사용중이었기 때문에 비효율적이라는 생각이 들었다

Like폴더에 내부 컴포넌트로 wrapped컴포넌트를 만들어서 contextApi를 호출하고 받은 값과, state에 따라 좋아요 추가, 취소 api를 실행하는 handler함수(+그 외 필요한 값들)를 Like컴포넌트에 Props으로 넘겨주었다.

sideEffect가 발생할 수 있는 로직들을 분리해서 상위컴포넌트로 감싸준 것. storyBook에는 Like컴포넌트만 불러와서 직접 props값을 넣어 사용하면 된다

// Like/Wrapped.jsx - Container 컴포넌트
export const LikeWrapped = ({ id, isLiked, likeCount }) => {
  const { userInfo } = useUser();

  const handleClick = async state => {
    state ? await delLikeSeries(id) : await addLikeSeries(id);
  };

  return (
    <Like
      seriesId={id}
      isLogin={userInfo.userId}
      isLiked={isLiked}
      likeCount={likeCount}
      onClick={handleClick}
    />
  );
};
// Like/index.jsx - Presentational 컴포넌트
export const Like = ({ isLogin, isLiked, likeCount, onClick }) => {
  const [state, toggle] = useToggle();
  const [count, setCount] = useState(0);

  useEffect(() => {
    isLiked && toggle();
    setCount(likeCount);
  }, [likeCount, isLiked]);

  const addLike = async () => {
    setCount(count + 1);
    onClick && onClick(state);
  };

  const cancleLike = async () => {
    setCount(count - 1);
    onClick && onClick(state);
  };

  const handleClick = () => {
    if (!isLogin) {
      return;
    }
    toggle();
    state ? cancleLike() : addLike();
  };

  return (
    <Container onClick={handleClick}>
      <IconWrapper color={isLogin ? theme.color.red : theme.color.gray}>
        {state ? <Icon.Like /> : <Icon.LikeBorder />}
      </IconWrapper>
      {typeof likeCount === 'boolean' ? '' : <Count>{count}</Count>}
    </Container>
  );
};

token을 interceptor에서 설정해줘야하는 이유
기존 - 전역 변수로 토큰을 저장했기 때문에 로그아웃을 해 토큰을 제거해도 남아있던 토큰을 가져와 요청 시에 같이 보내졌다
해결 - interceptor내부에서 매번 토큰을 불러와 요청할 때마다 토큰을 가져오게 했다

import axios from 'axios';

const { REACT_APP_API_END_POINT } = process.env;
// const token = sessionStorage.getItem('authorization');

const request = axios.create({
  baseURL: `${REACT_APP_API_END_POINT}`,
  timeout: 5000,
  // headers: {
  //   ...(token && { Authorization: `Bearer ${JSON.parse(token)}` }),
  // },
});

request.interceptors.request.use(
  config => {
    const TOKEN = sessionStorage.getItem('authorization');
    if (!TOKEN) return config;
    // eslint-disable-next-line no-param-reassign
    config.headers.Authorization = `Bearer ${JSON.parse(TOKEN)}`;
    return config;
  },
  error => Promise.reject(error),
);

request.interceptors.response.use(
  response => response,
  error => Promise.reject(error),
);

export default request;
profile
#프론트엔드

0개의 댓글