LIKE 버튼 구현 UI는 아래와 같이 스타일을 적용했다. Like 버튼의 데이터는 글, 날짜, 작성자와 동일하게 가져왔다. Like 버튼은 데이터만 가져오면 끝나는게 아니다. 누를 때 마다 데이터가 업데이트 되어야 하고, 이미 눌렀다면 다시 뺀 값이 업데이트 되어야한다. api는 게시물 번호와, 유저명을 받아 해당 게시물을 찾아서 like배열에 유저명을 넣는 식으로 작성했다. like배열에 이미 유저명이 있으면 배열에서 유저명을 제거해서 다시 돌려준다. /** * @path {PATCH} http://localhost:8000/api/posts/like * @description 좋아요 수 변경 * @returns {post} */ router.patch('/posts/like', async (req,..
전체 글 가져오는 기능 Hook으로 만들어 사용 전체글을 가져오는 기능을 필요로 하는 페이지가 점점 많아지다보니 페이지마다 동일한 코드를 작성할 수 없었다. 그래서 Hook으로 만들어 필요한 정보를 리턴해 원하는 페이지에서 데이터를 가져가다 쓸 수 있도록 했다. 문제는 useQuery로 받아온 데이터는 객체로 받는데 보통 객체를 배열로 변환하는 함수를 사용하곤 하지만 무슨이유인지 배열로 변환할 수가 없었다. 그래서 아래와 같이 for in문을 사용해 객체 하나씩 돌면서 원하는 배열에 저장하는 방법을 사용할 수 밖에 없었다. export const useGetAllposts = () => { const { data: postData, error } = useQuery( ['allPosts'], async ..
전체 유저에서 접속중인 유저만 불들어오도록 변경 서버에서 전체 유저 리스트를 받아와 현재 온라인인 유저만 불이 들어오도록 했다. 일단 useQuery를 사용한 서버의 전체 유저 데이터를 받아왔다. const { allUsers } = useAllUsers(); 그리고 실시간으로 접속중인 유저의 데이터는 socket.io를 사용해서 가져오고 allUsers, onlineList는 모두 이름 순으로 정렬시켰다. useEffect(() => { // 서버에서 온라인 리스트 배열로 받음 socket?.on('onlineList', (data) => { // 배열에서 중복요소 제거해서 새로운 배열 생성 const userArray = data.filter((ele, i) => { return data.indexO..
유저 실시간 접속상태 socketio로 유저 접속 시 백에서 배열에 저장해놨다가 중복검사를 해서 돌려주는 코드를 작성했었다. 그 배열을 돌려주는 객체에서 토큰과 유저명을 가져와 로그인중인지 확인 하는 방법을 선택했지만, 그러려면 useQuery랑 같이 사용해야하고 그 과정이 너무 복잡했다. socket.io만 사용해서 실시간으로 접속상태를 바꾸고 싶어서 소켓을 통해 데이터를 주고 받고 접속하면 온라인 상태인 것 까지는 성공했다. 하지만 브라우저를 종료할 경우 실시간으로 접속상태가 바뀌지도 않고 로그아웃이 되지도 않았다. 하루종일 너무 과몰입해서 머리가 조금 꽉 막힌 상태여서 조금 쉬었다가 다시 시도해봤다. // 서버 const SocketIO = require('socket.io'); module.exp..
포스트 클릭 시 글번호로 찾아 해당 페이지로 이동 기능 글을 누르면 해당 글의 페이지로 이동되는 기능을 추가했다. 일단 글을 누르면 서버로 글의 번호를 보내고 const Post = ({ post, userName, postDate, postId }) => { const navigate = useNavigate(); const onPostHandler = () => { axios .get(`api/posts/${postId[0]}`, { withCredentials: true }) .then((res) => { console.log(res.data); navigate(`/posts/${res.data}`); }) .catch((err) => console.log(err)); }; return ( 글내용:..
랜딩페이지 레이아웃 설정 메인 랜딩페이지를 그냥 기본적인 구조로 만들었다. NavBar: 로고와 로그인/로그아웃/내정보 기능 Write: 바로 글 작성 할 수 있는 공간 TopPosts: 좋아요를 많이 받은 순서로 정렬된 글 RecentPosts: 최근에 등록된 순서로 정렬된 글 UsersStatus: 실시간으로 접속하고있는 유저리스트 Footer: 개발자 정보 및 기타 등 크게 이렇게 메인 컴포넌트들로만 나눠놨고 기능을 구현하면서 디테일을 잡아갈 예정이다. 글 작성 기능 추가 메인 랜딩페이지에 글 작성을 바로할 수 있는 컴포넌트를 만들어놨다. 한글로만 작성할 수 있도록 정규표현식과 여러 조건들을 추가했다. const onSubmit = useCallback( (event) => { event.preve..
토스트 라이브러리 추가 레드핫 토스트 라이브러리를 설치해서 성공/실패 시 토스트알림으로 나오게 구현했다. 예를들어 로그인 컴포넌트에서 토스트를 하면 랜딩페이지로 넘어가면서 토스트가 먹통이 되는 경우가 생겼는데, 이때 각페이지마자 Toast Provider를 추가하는게 아니라 메인 App컴포넌트 아래에만 Toast Provider를 추가하니 해결이 됐다. import App from './App'; import GlobalStyle from '@styles/global'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-..
이번 주말동안 크게 한 것은 로그인 상태관리(서버)를 Redux에서 ReactQuery로 바꿨다는 점 작업하는동안 크게 느꼈던 것 부터 적고가자.. Redux는 클라이언트의 상태관리, React Query는 서버의 상태관리 HTTP 통신 시 요청(requset)과 응답(response)의 데이터를 꼭 확인하면서 작업하자. useQuery의 Promise함수는 꼭 response를 return을 해야 data에 값이 들어온다. const { data, isLoading, error } = useQuery( ['isLoggedIn'], async () => await axios .get('/api/users') .then((res) => { ✅ if (res.data.isAuth === false) retu..
유저 인증용 스키마 작성 MongoDB에 저장할 데이터 구조 즉, schema를 작성하고 외부에서 사용할 수 있도록 export 했다. 일단은 유저 회원가입 및 로그인에 필요한 내용만 작성했다. root에서 model 디렉토리를 만들고 그안에 User.js 파일을 생성했다. const mongoose = require('mongoose'); const saltRounds = 10; /* userSchema */ const userSchema = new mongoose.Schema( { nickname: { type: String, maxlength: 10, trim: true, unique: true, // required: true, }, email: { type: String, trim: true, ..