SENTENCE U | Day 7 (랜딩페이지 레이아웃/글 작성/react-query)

블로그 이사 완료·2023년 1월 26일
0
post-thumbnail

랜딩페이지 레이아웃 설정

메인 랜딩페이지를 그냥 기본적인 구조로 만들었다.

  • NavBar: 로고와 로그인/로그아웃/내정보 기능
  • Write: 바로 글 작성 할 수 있는 공간
  • TopPosts: 좋아요를 많이 받은 순서로 정렬된 글
  • RecentPosts: 최근에 등록된 순서로 정렬된 글
  • UsersStatus: 실시간으로 접속하고있는 유저리스트
  • Footer: 개발자 정보 및 기타 등

크게 이렇게 메인 컴포넌트들로만 나눠놨고 기능을 구현하면서 디테일을 잡아갈 예정이다.


글 작성 기능 추가

메인 랜딩페이지에 글 작성을 바로할 수 있는 컴포넌트를 만들어놨다.

한글로만 작성할 수 있도록 정규표현식과 여러 조건들을 추가했다.

const onSubmit = useCallback(
    (event) => {
      event.preventDefault();
      const regexp = /^[가-힣.,!%\s]+$/g;
      if (!useUserLoginStatus) toast.error('로그인 후 이용하실 수 있습니다.');
      if (!sentence) toast.error('문장을 적어주세요.');
      if (sentence && userName && userId && userLoginStatus) {
        if (sentence.length >= 20) {
          toast.error('최대 글자 수를 초과했습니다.');
        } else if (!regexp.test(sentence)) {
          toast.error('한글로 된 문장으로만 작성이 가능합니다.');
        } else {
          axios
            .post('/api/posts', { userId, userName, sentence })
            .then((res) => {
              toast.success('작성 성공!');
              setSentence('');
            })
            .catch((error) => {
              console.log(error);
              toast.error('오류가 발생했습니다.');
            });
        }
      }
    },
    [sentence, userId, userName, userLoginStatus],
  );

한글로만 이루어진 문장만 보고싶었다.


10초마다 실시간 글 불러오기

등록된 문장들을 최신순으로 보여주도록 api를 시간순으로 정렬한 데이터를 가져오도록 작성했다.

/**
 * @path {GET} http://localhost:8000/api/posts
 * @description 전체 글 가져오기
 * @returns {postSuccess}
 */
router.get('/posts', async (req, res) => {
  try {
    const allPost = await Post.find({}).sort({ createdAt: -1 });
    if (!allPost) return res.status(403).json({ loadAllPosts: false });
    return res.status(200).json(allPost);
  } catch (error) {
    console.log('에러: ', error);
    return res.status(403).json(error.errors);
  }
});

오늘의 큰 문제는 리액트쿼리로 받아온 데이터는 객체라서 렌더링을 할 수가 없었다.

그래서 각각 원하는 데이터를 배열에 넣어서 렌더링할 수 있도록 구현했다. 여기는 나중에 데이터 자체를 배열로 가져올 수 있도록 다시 설정해봐야겠다.

const RecentPosts = () => {
  const { data, error } = useQuery(
    ['allPosts'],
    async () => {
      return await axios
        .get('/api/posts')
        .then((res) => {
          return res.data;
        })
        .catch((error) => {
          console.log(error);
        });
    },
    {
      staleTime: 10000, // stale상태 제한 시간
      cacheTime: Infinity, // 캐싱 시간
      refetchInterval: 10000, // 10초 주기로 리패치
    },
  );

  const posts = [];
  const userName = [];
  const date = [];
  for (const key in data) {
    posts.push(data[key].sentence);
    userName.push(data[key].userName);
    date.push(data[key].createdAt);
  }

  return (
    <Container>
      <div>RecentPosts</div>
      {error ? (
        <div>{error}</div>
      ) : (
        posts.map((post, i) => (
          <Post key={i}>
            글내용: {post}, 작성자: {userName[i]}, 작성일자: {date[i]}
          </Post>
        ))
      )}
    </Container>
  );
};

그리고 실시간으로 최신 글을 불러와서 렌더링 하고 싶어서 react-query의 refetch인터벌 옵션을 10초로 설정했다.

그럼 10초마다 최신 글을 불러와서 해당 컴포넌트만 리렌더링할 수 있게됐다.

profile
https://kyledev.tistory.com/

0개의 댓글