앞에서 말했듯이, 본인과 팔로잉한 유저들의 게시글들을 보여주는 홈화면을 제작한다.
1. HomeContainer 작성
const HomeContainer = () => {
const [postList, setPostList] = useState(); // 게시글 리스트
const [postIndex, setPostIndex] = useState(); // 게시글의 파일 순서에 대한 처리를 위한 배열
useEffect(() => {
withJwtAxios.get('/post-list')
.then((res) => {
setPostList(res.data.postList);
setPostIndex(new Array(res.data.postList.length).fill(0));
});
}, [])
// 왼쪽 버튼을 눌렸을 때, 파일의 인덱스를 1 감소시킨다.
const onClickLeft = (idx) => {
if(postIndex[idx] > 0) {
const temp = JSON.parse(JSON.stringify(postIndex));
temp[idx] -= 1
setPostIndex(temp);
}
}
// 왼쪽 버튼을 눌렸을 때, 파일의 인덱스를 1 증가시킨다.
const onClickRight = (idx) => {
const postFileLen = postList[idx].postFileList.length;
if(postIndex[idx] < postFileLen -1) {
const temp = JSON.parse(JSON.stringify(postIndex));
temp[idx] += 1
setPostIndex(temp);
}
}
return (
<div className={style.home_container}>
<PostRender postList={postList} postIndex={postIndex} onClickLeft={onClickLeft} onClickRight={onClickRight}/>
</div>
);
};
export default HomeContainer;
- HomeContainer가 랜더링될때마다 postList를 가져와 저장하는 기능을 useEffect안에 작성하였다.
- postIndex, onClickLeft, onClickRight는 게시글의 파일 순서에 대한 처리를 하기위해 작성하였다.
2. PostRender.js 작성
- 이 컴포넌트는 받아온 postList를 각각의 컨테이너에 담아 출력시키는 컴포넌트이다.
- props로 postList, postIndex, onClickLeft, onClickRight 를 받아온다.
const PostRender = (props) => {
const postList = props.postList;
const postIndex = props.postIndex;
const onClickLeft = props.onClickLeft;
const onClickRight = props.onClickRight;
return (
<>
{postList !== undefined?
postList.map((post, idx) => {
const user = post.user;
const postFileList = post.postFileList;
return(
<div key={idx} className={style.post_container}>
{/* 게시글의 윗 부분의 디자인 -> 프로필 사진과 닉네임, 그리고 추가적인 메뉴들을 구성 */}
<div className={style.post_header}>
<div className={style.post_header_profile}>
<img className={style.profile_thumbnail} src={Static_Base_Url + user.profileUrl}/>
<div>{user.nickname}</div>
</div>
<div className={style.post_header_menu}>
<i className="bi bi-three-dots fs-3"></i>
</div>
</div>
{/* 게시글의 컨텐츠를 보여주는 부분 */}
<PostFile postFileList={postFileList} postFileList={postFileList} idx={idx} postIndex={postIndex} onClickLeft={onClickLeft} onClickRight={onClickRight}/>
{/* 게시글의 좋아요, 댓글들을 보여주는 부분 */}
<div className={style.post_icon_container}>
<div className={style.post_icon}>
<i className='bi bi-suit-heart fs-3'/>
<i className='bi bi-chat fs-3' style={{marginLeft: '10px'}}/>
</div>
<div className={style.post_icon_num}>
<div style={{marginRight: '10px'}}>
좋아요 갯수 ,
</div>
<div>
댓글 갯수
</div>
</div>
</div>
{/* 게시글의 글을 보여주는 부분 */}
<div className={style.post_content_container}>
<div className={style.post_content_nickname}>
{user.nickname}
</div>
<div className={style.post_content}>
{post.content.slice(1, post.content.length-1)}
</div>
</div>
</div>
)
})
:
<div>게시글이 없습니다.</div>
}
</>
);
};
export default PostRender;
- 크게 헤더, 컨텐츠내용, 좋아요/채팅, 게시글 순서로 보여준다.
- 컨텐츠내용에 대한 부분은 길어져서 PostFile이라는 컴포넌트로 따로 빼주었다.
3. PostFile.js
- 컨텐츠 내용들을 보여주는 컴포넌트이다.
- props로 postFile리스트, 게시글 인덱스, 해당 게시글 컨텐츠의 인덱스, 그리고 onClickLeft/Right 메서드를 받아온다.
const PostFile = (props) => {
const postFileList = props.postFileList;
const idx = props.idx;
const postIndex = props.postIndex;
const onClickLeft = props.onClickLeft;
const onClickRight = props.onClickRight;
// 파일이 동영상인지, 이미지인지 판단하여 다르게 랜더링한다.
const fileRender = (url) => {
const extension = url.split('/').pop().split('.').pop();
if(['mp4', 'mov', 'avi', 'wmv', 'MP4', 'MOV', 'AVI', 'WMV'].includes(extension)) {
return(
<video className={style.post_file} src={url} controls />
)
} else {
return(
<img className={style.post_file} src={url} />
)
}
}
return (
<div className={style.post_file_container}>
<div className={style.post_file_arrow_left} onClick={() => onClickLeft(idx)} style={{display: postIndex[idx] === 0 ? 'none' : 'inherit'}}>
<i className="bi bi-arrow-left-circle"></i>
</div>
{fileRender(Static_Base_Url + postFileList[postIndex[idx]].fileUrl)}
<div className={style.post_file_arrow_right} onClick={() => onClickRight(idx)} style={{display: postIndex[idx] === postFileList.length-1 ? 'none' : 'inherit'}}>
<i className="bi bi-arrow-right-circle"></i>
</div>
</div>
);
};
export default PostFile;
4. 동작 모습
'Web > 인스타 클론 코딩' 카테고리의 다른 글
[인스타그램 클론코딩] 09. 게시물 좋아요 기능 구현(Front-End) (0) | 2023.02.04 |
---|---|
[인스타그램 클론코딩] 09. 게시물 좋아요 기능 구현(Back-End) (0) | 2023.02.04 |
[인스타그램 클론코딩] 08. 홈 화면 구현(Back-End) (0) | 2023.02.03 |
[인스타그램 클론코딩] 07. 팔로우 기능 구현(Back-End) (0) | 2023.02.02 |
[인스타그램 클론코딩] 07. 팔로우 기능 구현(Front-End) (0) | 2023.02.02 |