티스토리 뷰

안녕하세요 강정호입니다

 

오늘은 인스타그램 클론 코딩에서 슬라이더 기능을 개발해보겠습니다.

슬라이더 기능 : 사진이 여러개일떄 일정 시간이 지난 후에 자동으로 다음 사진이 보여질 수 있도록 하는 것.

 

슬라이더 구현 로직을 살펴보겠습니다.

PostContainer.js

import React, { useState, useEffect } from "react";
import PostPresenter from "./PostPresenter";
import PropTypes from "prop-types";
import useInput from "../../Hooks/useInput";

// 입력받은 매개인자
const PostContainer = ({id, 
                        user, 
                        files, /** 사진id, url이 배열로 존재*/
                        likeCount,
                        isLiked,
                        comments,
                        createdAt,
                        caption,
                        location}) => {
    
    const [isLikedState, setIsLiked] = useState(isLiked);
    const [likeCountState, setLikeCount] = useState(likeCount);
    const [currentItem, setCurrentItem] = useState(0);

    const slide = () => {
        // files 배열의 총 길이 구한다
        const totalFiles = files.length;

        if(currentItem === totalFiles - 1){ // 사진이 오직 1장이라면 3초 후에도 현재 사진을 보여준다
            setTimeout(() => setCurrentItem(0), 3000);
        }else{ // 사진이 2장이상이라면 3초후에는 다음 배열의 사진을 보여준다
            setTimeout(() => setCurrentItem(currentItem + 1), 3000);
        }
    };

    const comment = useInput("");

    // useEffect : 컴포넌트가 렌더링될 때마다 currentItem +1씩 하여 사진을 변경
    useEffect(() => {
        slide();
    }, [currentItem]);

    return (
        <PostPresenter
            user={user}
            files={files}
            likeCount={likeCountState}
            isLiked={isLikedState}
            comments={comments}
            createdAt={createdAt}
            newComment={comment}
            setIsLiked={setIsLiked}
            setLikeCount={setLikeCount}
            currentItem={currentItem}
        />

    );
}

1) const [currentItem, setCurrentItem] = useState(0);

currentItem을 현재 사진이라고 했을 때, 최초 현재사진의 배열순서는 0으로 초기화 합니다.

 

2) slide() 함수 구현

files.length를 사용하여 1개의 Post에 업로드 된 사진 배열의 길이를 알아내어 총 개수를 확인합니다.

총 개수가 1개일 경우에는 현재 사진만 보여줍니다.

하지만 2개 이상일 경우에는 3초 후에 setCurrentItem 훅을 사용하여 다음 사진을 보여주게 됩니다.

그리고 currentItem과 사진의 총개수가 일치하면 다시 처음 사진을 보여줍니다.

 

3) currentItem 값을 PostPresenter.js로 넘기기

files와 함께 currentItem 값을 PostPresenter.js로 넘겨서 보여주어야 할 사진정보를 전달합니다.

 

PostPresenter.js

export default ({
    user: {userName, avatar},
    location,
    files,
    isLiked,
    likeCount,
    createdAt,
    newComment,
    currentItem
}) => (
    <Post>
        <Header>
            <Avatar size="sm" url={avatar} />
            <UserColumn>
                <FatText text={userName} />
                <Location>{location}</Location>
            </UserColumn>
        </Header>
        <Files>
            {files && files.map((file, index) => <File id={file.id} src={file.url} showing={index === currentItem}/>)}
        </Files>
        <Meta>
            <Buttons>
                <Button>{isLiked ? <HeartFull /> : <HeartEmpty /> }</Button>
                <Button>
                    <Comment />
                </Button>
            </Buttons>
            <FatText text={likeCount === 1 ? "1 like" : `${likeCount} likes`} />
            <Timestamp>{createdAt}</Timestamp>
            <Textarea placeholder="Add a comment..." {...newComment} />
        </Meta>
    </Post>
);

1) {files && files.map((file, index) => <File id={file.id} src={file.url} showing={index === currentItem}/>)}

files를 반복문을 돌리는 map 함수를 사용합니다. 이 때 배열의 순서를 나타내는 index 변수를 사용하여 currentItem과 일치하면 보여줄 수 있도록 옵션을 설정합니다.

 

댓글