-
Social Media 만들기 - 16) Discover - loadmore 버튼 구현하기NODE.JS 2021. 7. 30. 23:30
loadmore 버튼을 구현해보자.
discoverRouter를 만들어준다.
파일을 랜덤으로 num(로드모어 버튼 누를때마다 페이지수 증가 * limit)
const express = require('express') const {Post} = require('../models/Post') const {auth} = require('../middleware/auth') const { User } = require('../models/User') const discoverRouter = express.Router() discoverRouter.get('/', auth, async(req, res)=>{ try{ const user = await User.findOne({_id:req.user.id}) const newArr=[...user.following, req.user.id] const num = req.query.num || 9; const posts= await Post.aggregate([ {$match: {user:{$nin: newArr}}}, {$sample: {size:Number(num)}}, ]) return res.json({ result:posts.length, posts }) }catch(err){ return res.status(500).json({message:err.message}) } }) module.exports = discoverRouter
server.js
app.use('/api/discover', require('./routes/discoverRouter'));
postconstants.js
export const GET_DISCOVER_POST_REQUEST = 'GET_DISCOVER_POST_REQUEST' export const GET_DISCOVER_POST_SUCCESS = 'GET_DISCOVER_POST_SUCCESS' export const GET_DISCOVER_POST_FAIL = 'GET_DISCOVER_POST_FAIL' export const GET_DISCOVER_POST_UPDATE = 'GET_DISCOVER_POST_UPDATE'
postActions.js
export const getDiscoverPost= ()=>async(dispatch, getState)=>{ dispatch({ type:GET_DISCOVER_POST_REQUEST, payload:{loading:true} }) const {userLogin: {userInfo}} = getState(); try{ const res = await axios.get('/api/discover',{ headers:{authorization:`Bearer ${userInfo.token}`}, }) dispatch({ type:GET_DISCOVER_POST_SUCCESS, payload:{posts:res.data.posts, result:res.data.result} }) }catch(error){ dispatch({ type:GET_DISCOVER_POST_FAIL, payload: error.response && error.response.data.message ? error.response.data.message : error.message }) } }
postReducer.js
export const postDiscoverReducer = (state={}, action)=>{ switch(action.type){ case GET_DISCOVER_POST_REQUEST: return {...state, loading:true, success:false} case GET_DISCOVER_POST_SUCCESS: return {...state,loading:false, success:true, discoverpost:[...action.payload.posts], result:action.payload.result, firstLoad:true} case GET_DISCOVER_POST_FAIL: return {...state,loading:false, success:false, error:action.payload} case GET_DISCOVER_POST_UPDATE: return {...state, discoverpost:action.payload.posts, result:action.payload.result} default: return state } }
store.js
discoverpost:postDiscoverReducer,
Discover.js
데이터 처음 받아올때와 로드모어 버튼으로 더 받아올때를 나누기 위해서 firstload를 인자로 넘긴다.
(처음 데이터 받아오기 전에만 firstLoad false 이다. )
import axios from 'axios' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import Loading from '../component/Loading' import PostThumb from '../component/PostThumb' import { getDiscoverPost } from '../_actions/postActions' import { GET_DISCOVER_POST_RESET, GET_DISCOVER_POST_UPDATE } from '../_constants/postConstants' function Discover({props}) { const userLogin = useSelector(state => state.userLogin) const {userInfo} = userLogin if(!userInfo){ props.history.push('/login') } const [skip, setSkip] = useState(0) const [limit, setLimit] = useState(3) const [load, setLoad] = useState(false) const [page, setPage] = useState(2) const [posts, setPosts] = useState([]) const dispatch = useDispatch(); const discoverpost = useSelector(state => state.discoverpost) const {discoverpost:discoveredpost, loading, result, firstLoad} = discoverpost; useEffect(() => { if(!firstLoad){ dispatch(getDiscoverPost()) } },[dispatch, firstLoad,page, limit]) const onLoadMore = async() =>{ setLoad(true) const res = await axios.get(`/api/discover?num=${page*9}`,{ headers:{authorization:`Bearer ${userInfo.token}`}, }) dispatch({ type:GET_DISCOVER_POST_UPDATE, payload:res.data }) setPage(page+1) setLoad(false) } return ( <div> { loading ? <Loading></Loading> : discoveredpost && <PostThumb posts={discoveredpost} result={discoveredpost} /> } { load && <Loading></Loading> } { !loading && result<9*(page-1) ? '': <button className="btn btn-dark mx-auto d-block" onClick={onLoadMore}>LoadMore</button> } </div> ) } export default Discover
postThumb.js
(여기서 ? 안써주면 왜 지랄나는지 모를...ㅠ)
↓
(댓글로 알려주셔서 내용을 추가한다!🙌)
여기서 ?는 optional chaning 연산자로 null이나 undefined와 같은 값에 대한 예외처리를 자동화 해주는 것으로 객체가 존재하지 않으면 undefined를 반환한다.
(참고 사이트)
↓
자바스크립트 물음표, 물음표 두개 연산자의 정체
이게 무슨 문법인가 해서 구글 검색창에 자바스크립트 물음표를 쳐봤는데, 물음표 두개라는 검색어가 바로 뜨더라. 그런데도 검색결과를 보면 죄다 삼항 연산자에 대한 이야기들만 늘어놓고 있
lunuy.tistory.com
import React from 'react' import {Link} from 'react-router-dom' function PostThumb({posts, result}) { if(result ===0) return <h2 className="text-center text-danger">No Post</h2> return ( <div className="post_thumb"> { posts.map(post=>( <Link key={post._id} to={`/post/${post._id}`}> <div className="post_thumb_display"> { // console.log(post.images[0]) post.images[0]?.config.url.match(/video/i) ? <video controls src={post.images[0]?.data} alt={post.images[0]?.data}></video> : <img src={post.images[0]?.data} alt={post.images[0]?.data}></img> } <div className="post_thumb_menu"> <i className="far fa-heart">{post.likes.length}</i> <i className="far fa-comment">{post.comments.length}</i> </div> </div> </Link> )) } </div> ) } export default PostThumb
'NODE.JS' 카테고리의 다른 글
Social Media 만들기 - 18) SavePost 구현하기 (0) 2021.08.01 Social Media 만들기 - 17) share, suggestion 구현하기 (0) 2021.07.31 Social Media 만들기 - 16) profile post, detail post 구현하기 (0) 2021.07.19 Social Media 만들기 - 15) create, like, update, delete comment 구현하기 (0) 2021.07.16 Social Media 만들기 - 14) like, unlike post 구현하기 (0) 2021.07.13