목차
반응형
랜딩페이지 레이아웃 설정
메인 랜딩페이지를 그냥 기본적인 구조로 만들었다.
- 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를 시간순으로 정렬한 데이터를 가져오도록 작성했다.
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초마다 최신 글을 불러와서 해당 컴포넌트만 리렌더링할 수 있게됐다.
반응형