팔로우 & 언팔로우(프로필 페이지상)
저번시간에는 게시글에 있는 버튼을 통해 팔로우 언팔로우 기능을 구현하는 작업을 진행하였습니다.
이번에는 프로필 페이지에 있는 팔로우 언팔로우 리스트를 통해 구현하는 작업을 해보도록 하겠습니다.
특징은 다음과 같습니다 .
일단 프로필 페이지에서 리스트 로드
팔로우/팔로잉 리스트가 같은 컴포넌트이기 때문에 header에 따른 다른 dispatch
반복문 속 고차함수 이용
저번시간에 팔로잉 (내가 상대방을 팔로우) 구현했기 때문에 지우는 것도 이용
상대방이 날 팔로우한걸 차단하는 기능(팔로워 삭제) 구현
프로필 페이지에서 팔로워 / 팔로잉 리스트 로드
프로필 페이지에서는 다음 두 액션을 dispatch해 서버로부터 데이터를 불러옵니다.
LOAD_FOLLOWERS_REQUEST
LOAD_FOLLOWINGS_REQUEST
물론 이에 대한 reducer나 saga도 작성해줘야 합니다.
컴포넌트가 마운트될때 dispatch가 일어날 수 있도록 useEffect를 사용해주겠습니다.
useEffect(() => {
dispatch({ type: LOAD_FOLLOWERS_REQUEST });
dispatch({ type: LOAD_FOLLOWINGS_REQUEST });
}, [dispatch]);
그리고 백앤드 user 라우터에서 목록을 보내주도록 하겠습니다.
단계는 다음과 같습니다.
조회 요청을 보낸 로그인된 유저정보를 가져온뒤
없으면 에러발생,
있다면 그 유저의 팔로워를 sequelize관계메소드로 가져와서
프론트로 보내준다.
팔로잉 목록도 이와 같습니다.
프로필 팔로워 가져오기
GET /user/followers
router.get('/followers',isLoggedIn, async(req,res,next)=>{
try {
//조회 요청을 보낸 즉, 로그인된 유저 정보를 먼저 찾는다.
const user = await User.findOne({where:{id:req.user.id}});
if(!user){return res.status(403).send('없는 유저')};
//있다면 Sequelize관계메소드를 이용해 목록을 가져온다.
const followers = await user.getFollowers();
//결과물을 전송한다.
res.status(200).json(followers);
} catch (e) {
console.error(e);
next(e);
}
})
프로필 팔로잉 가져오기
방법은 팔로워와 동일합니다.
관계태이블에 as를 통해 Followings/ Followes로 구분했기 때문에 이번에는 Followings를 가져오면 됩니다.
이번에는 추가적으로 가져올 Following의 유저데이터를 좀 커스텀 해주겠습니다.
router.get('/followings',isLoggedIn,async(req,res,next)=>{
try {
//조회 요청을 보낸 즉, 로그인된 유저 정보를 먼저 찾는다.
const user = await User.findOne({where: {id:req.user.id}});
if(!user){return res.statud(404).send('없는유저입니다.')};
//있다면 Sequelize관계메소드를 이용해 목록을 가져온다.
const followings = user.getFollowings({
model:User,
attributes:['id','nickname'],
});
//커스텀은 데이터들을 보내준다.
res.status(200).json(followings);
} catch (e) {
console.error(e);
next(e);
}
})
이렇게 데이터들을 줄여주게 된다면 우리는 큰 장점을 가지고 갈 수 있습니다.
서버간 데이터통신의 크기를 줄일 수 있다.
유저의 필요한 정보만 보내지기 때문에 보안을 강화할 수 있다.
프로필 페이지 안에서의 언팔로우 / 팔로워차단 구현
먼저 FollowList컴포넌트 입니다.
const dispatch = useDispatch();
const onCancel = (id) => {
if (header === "팔로잉") {
dispatch({
type: UNFOLLOW_REQUEST,
data: id,
});
} else {
dispatch({
type: REMOVE_FOLLOWER_REQUEST,
data: id,
});
}
};
header에는 '팔로잉' / '팔로우' 두가지 property중 하나가 이용되기 때문에 그를 이용한 조건을 걸어주었습니다.
만약 내가 상대방을 팔로우한 팔로잉이 아니면 나를 팔로우한 상대방에게서 지우는 기능을 구현합니다.
컴포넌트렌더링에서는 다음과 같이 해줍니다.
{/*반복문 안에서 온클릭같은게 있다면 반복문에 대한 데이터를 넘겨줄때가 있는데 이때 고차함수 유용 */}
<Card
actions={[
<StopOutlined key="stop" onClick={() => onCancel(item.id)} />,
//onClick={onCencel(item.id)}이렇게 하고, const onCencel=(id)=>()=>{}이렇게도 가능
]}
>
그렇다면 이제 상대가 팔로우한 나와의 관계를 다시 취소시켜 볼까요?
DELETE user/follower/:id
router.delete('follower/:id',isLoggedIn, async(req,res,next)=>{
try {
} catch (e) {
console.error(e);
next(e);
}
})
여기서 프론트에서 보내주는 URI parameter의 id는 상대방의 id여야 합니다.
상대방 유저의 모델로 들어가 목록중 나를 삭제해 주어야 하기 때문입니다.
// 여기서 받아올 URI parameter의 id는 상대방의 id입니다.
// 상대방 유저를 조회해 그중 상대방이 팔로우한 목록에서 로그인한 유저를 지워야 하기 때문입니다.
router.delete('follower/:id',isLoggedIn, async(req,res,next)=>{
try {
//상대방 User조회
const user = await User.findOne({where:{id:req.params.id}});
//상대방이 없다면 에러
if(!user){return res.status(403).send('상대방 유저가 없습니다.')};
//상대방입장에서 나를 팔로잉한것이기 때문에 following중 나를 삭제
await user.removeFollowing(req.user.id);
//리덕스 상태에서 상대방 아이디를 filter해주기 위해 보내준다.
res.status(200).json({id:parseInt(req.params.id, 10)});
} catch (e) {
console.error(e);
next(e);
}
});
생각보다 복잡하지는 않지만 router가 많아지면 많아질수록 뭔가 햇갈리는 부분들이 많아집니다.
주의하고 신중히 생각을 하며 작성해야만 합니다.
Last updated
Was this helpful?