[TIL_26] <react> webucks-react (3)

구민기·2021년 12월 6일
0

mission 4~8

  • 리스트 페이지에 하트 버튼
  • 커피 상세페이지의 하트 버튼

하트 버튼이 여러군데 사용되어서 Heart.js에 Heart 컴포넌트를 만들어서 재사용하였다.

mport React, { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faHeart as regularHeart } from "@fortawesome/free-regular-svg-icons"; //
import { faHeart as solidHeart } from "@fortawesome/free-solid-svg-icons";

function HeartBtn() {
  const [blankColor, setColor] = useState("black");

  const [blankOpacity, setBlankOpacity] = useState("0.5");

  const [solidOpacity, setSolidOpacity] = useState("0");

  function heartChange(e) {
    if (blankColor === "black") {
      e.preventDefault();
      setColor("red");
      setBlankOpacity("0.5");
      setSolidOpacity("0.5");
    } else {
      e.preventDefault();
      setColor("black");
      setBlankOpacity("0.5");
      setSolidOpacity("0");
    }
  }

  return (
    <div className="HeartBtn">
    <a className="heart" onClick={heartChange} href="">
    <i className="blankHeart"
	style={{ opacity: blankOpacity, color: blankColor }}>
    	<FontAwesomeIcon icon={regularHeart} />
    </i>
    <i className="solidHeart" style={{ opacity: solidOpacity }}>
  	<FontAwesomeIcon icon={solidHeart} />
    </i>
</a>
</div>
);
}

export default HeartBtn;

fontawesome 아이콘을 리액트에서 사용하는 법을 연습해볼 수 있었다.

  • 리뷰에 좋아요 버튼
  • 커피 상세페이지에 리뷰 달고 삭제 기능 구현

위 기능을 구현하면서 많은 어려움을 겪었다..

const [id, setId] = useState("");
const handleIdInput = (e) => {
  setId(e.target.value);
};

const [review, setReview] = useState("");
const handleReviewInput = (e) => {
  setReview(e.target.value);
};

const [reviewsList, setList] = useState([]);

const enter = (e) => {
  if (e.key === "Enter" && id && review) {
    setList(reviewsList.concat({ id: id, review: review }));
    setId("");
    setReview("");
  }
};

리뷰에 기록되는 id값과 comment를 객체에 담아서 그걸 배열안에 넣는 방식으로 리뷰리스트를 만들었다.

<section id="reviews">
  {reviewsList.map((el, index) => {
    return (
      <li key={index}>
        <span className="idOutput">{el.id}</span>
        <span className="reviewOutput">{el.review}</span>
        <button className="delete" id={index} onClick={deleteReview}>
          삭제
        </button>
        <LikeBtn id={index} /> // 좋아요 버튼 컴포넌트
      </li>
    );
})}
</section>

그리고 그 리스트를 map함수로 화면에 구현될수 있도록 변환시켜 주었다.

좋아요,싫어요 버튼을 구성을 할때 원래는 위와 같이 컴포넌트로 구성하지 않고 그냥 버튼 태그로 넣었다.
그랬더니 하나의 좋아요 혹은 싫어요버튼을 누르면 모두 다같이 변하는 문제가 발생했다.😂
원인을 찾고 싶었으나 못찾고 하트 버튼 처럼 컴포넌트처럼 만들어서 구현했다.

import React, { useState } from "react";
import "./LikeBtn.scss";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faThumbsUp } from "@fortawesome/free-solid-svg-icons";

function LikeBtn() {
  const [likeColor, setLikeColor] = useState("black");

  const [likeOpacity, setLikeOpacity] = useState("0.3");

  const [hateColor, setHateColor] = useState("black");

  const [hateOpacity, setHateOpacity] = useState("0.3");

  function likeChange(e) {
    if (likeColor === "black") {
      e.preventDefault();
      setLikeColor("blue");
      setLikeOpacity("0.6");
    } else {
      e.preventDefault();
      setLikeColor("black");
      setLikeOpacity("0.3");
    }
  }

  function hateChange(e) {
    if (hateColor === "black") {
      e.preventDefault();
      setHateColor("red");
      setHateOpacity("0.6");
    } else {
      e.preventDefault();
      setHateColor("black");
      setHateOpacity("0.3");
    }
  }

  return (
    <div className="LikeBtn">
      <div onClick={likeChange} className="like"
      style={{ color: likeColor, opacity: likeOpacity }}
      >
        <FontAwesomeIcon icon={faThumbsUp} />
      </div>
      <div onClick={hateChange} className="hate"
      style={{ color: hateColor, opacity: hateOpacity }}
      >
        <FontAwesomeIcon icon={faThumbsUp} />
      </div>
    </div>
	);
}

export default LikeBtn;

이번에는 삭제버튼에서 또 문제가 생겼다. 댓글은 삭제가 잘되는데 좋아요,싫어요 버튼은 무조건 마지막에 해당하는 것만 삭제가 되었다.
댓글 삭제 기능을 리스트에서 해당 index에 객체 값을 삭제해주고 다시 map함수를 실행되게 하는 방식으로 했는데
좋아요 버튼하고는 index값으로 묶이지 않아서 문제가 발생했을것 같다는 추측을 할뿐이었다.

// 기존의 제대로 작동되지 않는 코드
const deleteReview = (e) => {
  const num = Number(e.target.id);
  setList(
    reviewsList.filter((e) => {
      return reviewsList.indexOf(e) != num;
    })
  );
};

결국 우리팀원의 블로그를 참조하여 해당 부분을 해결하였다..ㅎㅎ ( 하늘님 감사합니다😄 )

const deleteReview = (e) => {
  e.target.parentElement.remove();
};

이벤트가 발생한 부모요소에 접근해서 제거해주는 방식이다.
알아두면 나중에도 유용하게 쓸 수 있을것 같다!

이렇게 어찌저찌 미션은 완료했지만 기능구현이 다가 아니구나를 다시한번 느끼게 되었다.

0개의 댓글