[인스타그램 클론코딩] 08. 홈 화면 구현(Front-End)

2023. 2. 3. 18:14·Web/인스타 클론 코딩

앞에서 말했듯이, 본인과 팔로잉한 유저들의 게시글들을 보여주는 홈화면을 제작한다.

 

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
'Web/인스타 클론 코딩' 카테고리의 다른 글
  • [인스타그램 클론코딩] 09. 게시물 좋아요 기능 구현(Front-End)
  • [인스타그램 클론코딩] 09. 게시물 좋아요 기능 구현(Back-End)
  • [인스타그램 클론코딩] 08. 홈 화면 구현(Back-End)
  • [인스타그램 클론코딩] 07. 팔로우 기능 구현(Back-End)
뚝딱뚝딱2
뚝딱뚝딱2
  • 뚝딱뚝딱2
    개발도상국
    뚝딱뚝딱2
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 공부
        • Java
        • Spring Boot
        • LORA
      • Web
        • 인스타 클론 코딩
        • GPT 응답 API 서버
        • Spring Boot 예외 처리
        • 코테 준비용 서비스 만들기
      • DevOps
        • 쿠버네티스
        • 서버 만들기
      • 코딩테스트
        • 알고리즘
      • 교육
        • 스파르타코딩클럽 - 내일배움단
        • 혼자 공부하는 컴퓨터 구조 운영체제
      • 잡다한것
  • 블로그 메뉴

    • 홈
  • 링크

    • GITHUB
  • 공지사항

  • 인기 글

  • 태그

    인스타그램
    리액트
    mapstruct
    스프링 부트
    예외
    클러스터
    MSA
    Entity
    스프링부트
    REST API
    react
    chat GPT
    spring boot
    백준
    클론코딩
    Java
    오블완
    티스토리챌린지
    쿠버네티스
    OpenAI API
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
뚝딱뚝딱2
[인스타그램 클론코딩] 08. 홈 화면 구현(Front-End)
상단으로

티스토리툴바