ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1차 프로젝트 기능구현
    bootcamp(with wecode)/회고록 2023. 3. 21. 21:30

    product list  page

    구현해야되는 기능으로는 

    1.  product list 화면 

    2. product image 좋아요 버튼 

    3. product image 마우스 호버시 장바구니 버튼 

    4. 장바구니 버튼 클릭시 모달창 생성 

    5. 장바구니 모달창에서 제품 사이즈 선택

    6. 사이즈, 색깔 필터 

     

     

     

     

    코드를 살펴보자

     

    1. product list 화면 

    //productlist.js
    
        <div className="product_list">
            <div className="list_container">
              {getData &&
                getData.map(
                  ({
                    id,
                    name,
                    price,
                    categories,
                    image_url,
                  }) => {
                    return (
                      <ProductListImage
                        key={id}
                        id={id}
                        name={name}
                        price={price}
                        categories={categories}
                        image_url={image_url}
                      />
                    );
                  }
                )}
            </div>
          </div>

    - product image 가 반복되므로 map 을 이용해 화면을 구성했다

    프로젝트 시작 전에는 map을 이해는 했지만 구현하는데 쉽지 않았었다

    반복되는 부분을 일단 전부 구현해 놓은후 반복에 해당되는 부분만 map으로 분류해서 작업해보니

    조금은 map에 대해서 이해가 가능했다  

    - map은 코드가 불필요하게 반복되는 부분을 효율적으로 줄여줄수 있는 방법이라 앞으로 자주 사용될 것 같다

    숙달 될 수 있도록 반복 학습이 필요하다

     

     

    2. product image 좋아요 버튼

    //좋아요 버튼.js
    
    	const [color, setColor] = useState('');
    
    		 <div className="like_button">
                <button
                  onClick={() => setColor(!color)}
                  className={color ? 'on' : ''}
                >
                  <span className="ico_shop ico_like" />
                </button>
              </div>

    - product image 오른쪽 상단에 좋아요 버튼, 클릭시 붉은색으로 변화

    - 버튼에 onClick 이벤트를 부여하고 setColor로 state 값을 관리하도록 지정했다 

    - product image 버튼 색깔이 바뀌는 부분까지 했지만 페이지 상단 Nav에 좋아요 버튼에 반영되지는 못했다 

    다음 프로젝트 때에는 Nav 좋아요 버튼에도 반영할 수 있도록 구현해 보고 싶다 

     

     

    3. product image 마우스 호버시 장바구니 버튼 

    //마우스 호버시 장바구니 버튼 생성.js		 
             
             const [modal, setModal] = useState(false);
             
             {isHover ? (
                <button
                  className="product_list_cart"
                  onClick={() => setModal(true)}
                >
                  장바구니담기
                </button>
              ) : (
                <button
                  className="product_list_cart_hover"
                  onClick={() => setModal(true)}
                >
                  장바구니담기
                </button>
              )}

    - 좋아요 버튼과 마찬가지로 버튼에 onClick 이벤트를 부여하고 setModal로 state 값을 관리하도록 지정했다 

    다른점은 초기값을 false로 정해서 호버가 되기 전에는 버튼이 보이지 않도록 구현했다

    - 호버는 삼항연산자를 사용했다

    삼항연산자 사용에 있어서 아직 미비한 면이 있다 좀더 빠르게 작성할 수 있도록 연습이 필요하다 

    - 버튼 창이 생성되는데 있어서 scss 애니메이션을 추가하여 좀더 보기 좋기 꾸몄다

     

     

    4. 장바구니 버튼 클릭시 모달창 생성 

         {modal && (
              <div className="modal_background">
                <div className="modal_box">
                  <div className="modal_box_option">
                    옵션
                    <button
                      onClick={() => setModal(false)}
                      className="ico_shop modal_close"
                      type="button"
                    >
                      <span className="ico_shop modal_close" />
                      닫기
                    </button>
                  </div>
                  <div className="modal_box_base">
                    <div className="modal_box_article">
                      <div className="modal_box_product_info_container">
                        <div className="modal_box_product_image">
                          <img
                            className="modal_box_product_image_shot"
                            src={image_url[0]}
                          />
                        </div>
                        <div className="modal_box_product_contents">
                          <h1 className="modal_box_product_contents_title">
                            {name}
                          </h1>
                          <p className="modal_box_product_contents_color">
                            {color}
                          </p>
                          <div className="modal_box_product_price">
                            {price}
                            <p className="modal_box_product_price_wrapper">
                              <span className="modal_box_product_price_wrapper_in">
                                {parseInt(price).toLocaleString()}
                              </span>
                            </p>
                          </div>
                        </div>
                      </div>
                      <div className="modal_box_product_guide_container">
                        <p className="modal_box_product_guide_title">정사이즈</p>
                        <div className="modal_box_product_guide_review">
                          <div className="modal_box_product_guide_review_bar">
                            <span className="modal_box_product_guide_review_bar_icon">
                              <span className="modal_box_product_guide_review_bar_icon_out" />
                              <p className="modal_box_product_guide_review_bar_icon_line" />
                            </span>
                          </div>
                          <div className="modal_box_product_guide_text_containter">
                            <span className="modal_box_product_guide_text_containter_small">
                              작아요
                            </span>
                            <span className="modal_box_product_guide_text_containter_regular">
                              적당해요
                            </span>
                            <span className="modal_box_product_guide_text_containter_big">
                              커요
                            </span>
                          </div>
                        </div>
                      </div>
                      <div className="modal_box_product_base_foot">
                        <div className="modal_box_product_base_foot_layer">
                          <button
                            className="modal_box_product_foot_button"
                            onClick={addCart}
                          >
                            장바구니 담기
                          </button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            )}

    - 모달창 안에 상품에 대한 정보가 담겨져 있어서 코드가 길다

    컴포넌트화 했으면 좀더 읽기 편했을 것 같다 이 부분을 refactoring 작업을 통해 수정, 보완해야겠다 

     

     

    5. 장바구니 모달창에서 제품 사이즈 선택

     

    //장바구니 모달창에서 제품 사이즈 선택.js
    
    
     		<div className="modal_box_product_body_containter">
                        <div className="modal_box_product_body_head">
                          <p className="modal_box_product_body_title">
                            사이즈(mm)선택
                          </p>
                        </div>
                        <div className="modal_box_product_body_option">
                          {BTN_COLOR.map(({ title, className }) => (
                            <SizeButton
                              key={id}
                              title={title}
                              className={className}
                              selectedSize={selectedSize}
                              setSelectedSize={setSelectedSize}
                            />
                          ))}
                        </div>
                      </div>

    - 사이즈 선택하는 버튼을 map을 돌려서 표현했다 

     

     

    6. 사이즈, 색깔 필터 

    //필터.js
    
    const Filter = () => {
      const [searchParams, setSearchParams] = useSearchParams();
    
      const colorArr = searchParams.getAll('color');
      useEffect(() => {
        searchParams.delete('size');
        searchParams.delete('color');
        setSearchParams(searchParams);
      }, []);
    
      const setColor = (value, e) => {
        if (colorArr.indexOf(value) === -1) {
          searchParams.append('color', value);
          setSearchParams(searchParams);
        } else {
          const search = searchParams.getAll('color');
          searchParams.delete('color');
          search
            .filter(list => list !== value)
            .forEach(value => {
              searchParams.append('color', value);
            });
          setSearchParams(searchParams);
        }
      };
    
      return (
        <div className="filter">
          <div className="filter_box">
            <form action="#none" method="post">
              구분
              <div className="filter_box_size">
                <br />
                <h3 className="filter_size" name="filter_size">
                  사 이 즈
                </h3>
    
                <div className="filter_size_button">
                  <ul className="filter_size_button_product">
                    {SIZE_BUTTON.map(({ id, size }) => (
                      <FilterSizeButton key={id} size={size} />
                    ))}
                  </ul>
                </div>
              </div>
              <div className="filter_box_price">
                <br />
                <h3 className="filter_price" name="filter_price">
                  가 격
                </h3>
                <progress
                  id="progress"
                  value="500"
                  min="0"
                  max="1000"
                  className="filter_price_progress"
                />
              </div>
              <div className="filter_box_color">
                <label>
                  <br />
                  <div className="filter_color" name="filter_color" type="checkbox">
                    색 상
                  </div>
                </label>
                <ul className="filter_color_button">
                  {COLOR_BUTTON.map(({ id, color }) => (
                    <li className="filter_color_button_record" key={id}>
                      <button
                        className={`filter_color_button_record_${color}`}
                        type="button"
                        onClick={e => setColor(color, e)}
                        value={color}
                      />
                    </li>
                  ))}
                </ul>
              </div>
            </form>
          </div>
        </div>
      );
    };
    
    export default Filter;
    
    const SIZE_BUTTON = [
      { id: 1, size: '220' },
      { id: 2, size: '230' },
      { id: 3, size: '240' },
      { id: 4, size: '250' },
      { id: 5, size: '260' },
      { id: 6, size: '270' },
      { id: 7, size: '280' },
      { id: 8, size: '290' },
      { id: 9, size: '300' },
    ];
    
    const COLOR_BUTTON = [
      { id: 1, color: 'black' },
      { id: 2, color: 'red' },
      { id: 3, color: 'yellow' },
    ];

    - 제일 아쉬운 부분이다

    - searchParams을 통해서 필터에 사이즈나 색깔이 바뀔 때마다 주소창에 반영 될수 있도록 했다. 

    - 다만 back에서 보내주는 데이터로 구현 했어야 했는데 이 부분을 소화하지 못했다

    상수데이터로만 구현했다는 점이 매우 아쉽다 

     

     

     

    기능구현을 마치고,,,

    - 여전히 수정 보완해야될 부분들이 많이 보인다. 주변 사람들에게 물어보면서 구현한 코드들도 많다.

    정확히 내가 알고 있다고 자신하기 어려운 부분들까지

    2차 프로젝트때에는 좀더 주도면밀하게 분석해가면서 개발자로서의 기능구현에 전문적인 사람이 되고자 한다.

    'bootcamp(with wecode) > 회고록' 카테고리의 다른 글

    기업협업 회고록  (0) 2023.05.22
    2차 프로젝트 회고록  (0) 2023.04.22
    2차 프로젝트 기능구현  (2) 2023.04.15
    1차 프로젝트 회고록  (0) 2023.03.21
Designed by Tistory.