[PROJECT] - RUSHOUR 1주 차

crystalee·2021년 8월 8일
4

RushOur Project 1주 차

기능 구현

  • 메인 캐로셀
  • 메인 리스트 캐로셀
  • 메인 사이드 배너 캐로셀

Main Carousel

sliderArr는 몇개의 사진을 넘길 것인지에 대한 값이며 slideLeft,slideRight 에서 x축을 얼마만큼 넘겨줄 것인지 설정해주고
메인 비주얼 이미지가 100% 씩 이동하며 더 이상 이동할 이미지가 없을 시 다시 첫 번째 이미지로 돌아오며 4초가 지나면 자동으로 이미지가 이동하는 기능을 구현했다.

데이터를 map 메소드를 통해 전해주고, translateX 라는 x 축을 이동시키는 transform 스타일을 주고 이동시킨다.

✍️JSX

import React, { Component } from 'react';
import './MainCarousel.scss';

class MainCarousel extends Component {
  constructor() {
    super();
    this.state = {
      sliderPosition: 0,
      sliderArr: [],
    };
  }

  componentDidMount() {
    fetch('/data/visualData.json')
      .then(res => res.json())
      .then(data => {
        this.setState({
          sliderArr: data,
        });
      });
    setInterval(this.slideRight, 4000);
  }

  slideLeft = () => {
    const { sliderPosition } = this.state;
    this.setState({
      sliderPosition: sliderPosition === 0 ? 0 : sliderPosition + 100,
    });
  };

  slideRight = () => {
    const { sliderPosition, sliderArr } = this.state;

    this.setState({
      sliderPosition:
        sliderPosition === -100 * (sliderArr.length - 1)
          ? 0
          : sliderPosition - 100,
    });
  };

  render() {
    const { sliderPosition, sliderArr } = this.state;

    return (
      <div className="visualWrap">
          <div className="visualSlide">
            <div
            className="imgWrap"
            style={{ transform: `translateX(${sliderPosition}%)` }}
          >
            {sliderArr &&
              sliderArr.map(sliderElement => {
                return   <img alt={sliderElement.alt} src={sliderElement.src} />;
              })}
            </div>

            <button className="leftButton" onClick={this.slideLeft}>
              <i class="fas fa-chevron-left">  </i>
            </button>
            <button className="rightButton" onClick={this.slideRight}>
              <i class="fas fa-chevron-right">  </i>
            </button>
          </div>
        </div>
    );
  }
}

export default MainCarousel;

✍️SCSS

.visualWrap {
  position: relative;
  height: 600px;
  background-color: blue;

  .visualSlide {
    overflow: hidden;
    height: 100%;

    .imgWrap {
      display: flex;
      transition: 1s all ease-in-out;

      img {
        flex-shrink: 0;
        object-fit: cover;
        width: 100%;
        height: 600px;
      }
    }
    .leftButton {
      position: absolute;
      transform: translateY(-50%);
      width: 60px;
      height: 60px;
      top: 50%;
      left: 150px;
      background: none;
      border: 1px solid #fff;
      color: #fff;
    }

    .rightButton {
      position: absolute;
      transform: translateY(-50%);
      width: 60px;
      height: 60px;
      top: 50%;
      right: 150px;
      background: none;
      border: 1px solid #fff;
      color: #fff;
    }
  }
}

🙅‍♀️ 오류

비주얼 이미지가 계속 100%로 넘어가지 않아 문제가 발생했고 이유는 flex-item 요소의 크기가 flex-container 요소의 크기보다 커서 난 오류였다. 해결 방법은 flex-shrink 속성을 사용하는데, 설정된 숫자값에 따라 flex-container 요소 내부에서 flex-item 요소의 크기를 축소시켰다.

flex-shrink : https://developer.mozilla.org/ko/docs/Web/CSS/flex-shrink

Main List Carousel

arrow 버튼을 눌러야 리스트가 이동하며 한 번 이동할 때마다 4개의 리스트가 한 번에 넘어가고 이동함에 따라 pagenation 숫자도 바뀌게 구현했다.

✍️JSX

import React, { Component } from 'react';
import MainListCom from './MainListCom';
import './MainList.scss';

class MainList extends Component {
  constructor() {
    super();
    this.state = {
      listArr: [],
      listSlider: 0,
    };
  }
  componentDidMount() {
    fetch('/data/MainListData.json')
      // fetch(`${API.PRODUCTLIST}`)
      .then(res => res.json())
      .then(data => {
        this.setState({
          listArr: data,
        });
        // console.log('api data', data);
      });
  }

  slideLeft = () => {
    const { listSlider } = this.state;
    this.setState({
      listSlider: listSlider === 0 ? 0 : listSlider + 100,
    });
  };

 slideRight = () => {
    const { sliderPosition, sliderArr } = this.state;

    this.setState({
      sliderPosition:
        sliderPosition === -100 * (sliderArr.length - 1)
          ? 0
          : sliderPosition - 100,
    });
  };
    this.setState({
      listSlider: currentSlider,
    });
  };

  render() {
    const { listArr, listSlider } = this.state;
    console.log('현재 슬라이더 리스트', listSlider);
    return (
      <section className="mainContents01">
        <div className="mainList">
          <h2>나만 알고 싶은 향기</h2>

          <ul
            className="listSlide"
            style={{ transform: `translateX(${listSlider}%)` }}
          >
            {listArr &&
              listArr.map(product => {
                return (
                  <MainListCom
                    key={product.id}
                    name={product.name}
                    price={product.price}
                    tag={product.tags}
                    img={product.thumbnail}
                  />
                );
              })}
          </ul>

          <div className="listButton">
            <button className="leftButton" onClick={this.slideLeft}>
              <i class="fas fa-chevron-left"></i>
            </button>
            <button className="rightButton" onClick={this.slideRight}>
              <i class="fas fa-chevron-right"></i>
            </button>
            <div className="pageCount">
              <span>{this.state.listSlider / -10 / 10 + 1}</span>
              <span>/</span>
              <span>{listArr && listArr.length / 4}</span>
            </div>
          </div>
        </div>
      </section>
    );
  }
}

export default MainList;

🙅‍♀️ 오류


4개의 리스트를 100%씩 이동하는 방법으로 구현하려 했으나 index의 길이 값에 따라 이동하는 x축의 길이가 계속 늘어나 이미지가 없어도 계속 슬라이드가 넘어가는 오류가 발생했다.

slideRight = () => {
    const { listSlider, listArr } = this.state;
    let currentSlider = listSlider;
    currentSlider = currentSlider + listSlider;

    console.log('버튼 누르기전', currentSlider);
    console.log('arr', listArr.length / 4);
    console.log('arr2', -100 * (listArr.length / 4));

    if (currentSlider <= -100 * (listArr.length / 4)) {
      currentSlider = -100;
    } else {
      currentSlider = listSlider + -100;
    }
    console.log('버튼 누른후', currentSlider);

    this.setState({
      listSlider: currentSlider,
    });
  };

해결 방법은 100% 씩 넘어가는 캐로셀을 index길이에서 나눠주고 그 나누어진 값만큼 x축으로 이동하게 구현했다.

Main Aside Carousel

absolute를 사용해 메인과 컨텐츠 사이에 걸치고 5초가 지나면 자동으로 이미지가 넘어가게 기능을 구현했다.

✍️JSX

import React, { Component } from 'react';
import './MainAside.scss';

class MainAside extends Component {
  constructor() {
    super();
    this.state = {
      listArr: [],
      listSlider: 0,
    };
  }
  componentDidMount() {
    fetch('/data/MainAsideData.json')
      // fetch(`${API.PRODUCTLIST}`)
      .then(res => res.json())
      .then(data => {
        this.setState({
          listArr: data,
        });
        // console.log('api data', data);
        setInterval(this.slideRight, 5000);
      });
  }

  slideLeft = () => {
    const { listSlider } = this.state;
    this.setState({
      listSlider: listSlider === 0 ? 0 : listSlider + 100,
    });
  };

  slideRight = () => {
    const { listSlider, listArr } = this.state;

    this.setState({
      listSlider:
        listSlider === -100 * (listArr.length - 1) ? 0 : listSlider - 100,
    });
  };

  render() {
    const { listArr, listSlider } = this.state;
    return (
      <section className="mainContents02">
        <div className="bannerList">
          <ul
            className="bannerImg"
            style={{ transform: `translateX(${listSlider}%)` }}
          >
            {listArr &&
              listArr.map(sliderElement => {
                return <img alt={sliderElement.alt} src={sliderElement.src} />;
              })}
          </ul>
        </div>
        <div className="asideButton">
          <button className="leftButton" onClick={this.slideLeft}>
            <i class="fas fa-chevron-left"></i>
          </button>
          <button className="rightButton" onClick={this.slideRight}>
            <i class="fas fa-chevron-right"></i>
          </button>
          <div className="pageCount">
            <span>{this.state.listSlider / -10 / 10 + 1}</span>
            <span>/</span>
            <span>{listArr && listArr.length}</span>
          </div>
        </div>
      </section>
    );
  }
}

export default MainAside;

1주차 프로젝트 중간 정리를 마치며 ❗️

라이브러리를 사용하지 않고 슬라이드를 구현해본 게 처음이어서 많이 어려웠고 재밌었다. 오류도 잦고 고민하는 시간도 길었지만 팀원들의 도움으로 오류를 해결해 나가는 것도 즐거웠다. 프로젝트하면서 팀원들 간의 소통이 얼마나 중요한지 깨달았고 첫 프로젝트인 만큼 버벅댔던 첫날보다 우리 팀원들의 소통 능력이 하루하루 나아지고 노력하는 모습이 정말 좋았다.
이제 백엔드와 같이 하는 작업을 준비하면서 프론트엔드 개념도 많이 공부하고 백엔드 용어도 많이 공부해야겠다고 생각했다.

profile
코린이 성장일기

4개의 댓글

comment-user-thumbnail
2021년 8월 8일

수정님 저도 코드 참고할게요!!!! 화이팅!💪

1개의 답글
comment-user-thumbnail
2021년 8월 10일

이게 그 전설의... 잘 보고 갑니다!

답글 달기