how do i make wishlist in react js

Viewed 329

I'm making wish list in react js.

I want that when i clicked wish button about something goods, the goods is added on wish list by boolean data "liked: true".

And i want that if i click one more when boolean data true, the goods is delete on wish list by boolean data "liked: false"

But now, when i clicked wish button, the liked data changed to true, but not added on wish list.

And, i clicked one more, but it didn't changed to false.

How can i fix my code?

This is my code.

import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
import "./goods.css";

const Goods  = (props) => {
  const [boards, setBoards] = useState({});
  const [images, setImages] = useState([]);
  const {id}  = useParams();
  const [isWishAdd, setIsWishAdd] = useState(false);
  const [wishCount, setWishCount] = useState(0); 

  const wishAddHandler = () => {
    setIsWishAdd(!isWishAdd);
  }

  const wishCountHandler = () => {
    wishAddHandler()
    if (!isWishAdd) {
      setWishCount(wishCount +1)
      fetch(`https://27.96.131.85:8443/api/likeBoards/${boards.id}`, {
        credentials: 'include',
        method: "POST",
        body: JSON.stringify({
         "liked": true
        }),
      })
      alert("찜 목록에 추가되었습니다.")
      console.log(boards)
      console.log("count+1")
    } else if (isWishAdd) {
      setWishCount(wishCount -1)
      fetch(`https://27.96.131.85:8443/api/likeBoards/${boards.id}`, {
        credentials: 'include',
        method: "DELETE",
        body: JSON.stringify({
          "liked": false
        })
      })
      alert("찜 목록에서 삭제되었습니다.")
      console.log(boards)
      console.log("count-1")
    }
  }    
  

  useEffect(() => {
    (async function () {
      const response = await axios.get(`https://27.96.131.85:8443/api/boards/${id}`, {
        withCredentials: true,
      });
      const boards = response.data;
      const images = boards.boardImages;
      console.log(response.data);

      // 게시글 정보 state에 저장
      setBoards(boards);
      setImages(images);

    })();
  }, []);

    return(
      <div id="goods">
        <p className="goodsTitle">상품 정보</p>
        <div className="images_container">
          {
            images.map((images) => {
              return (
                <img className="goodsImages"
                src={`https://27.96.131.85:8443/api/images/${images.id}`} />
              )
            })
          }
        </div>
       
        <div className="goodsContext">  
          <div className="goodsBoardTitle">
            {boards.title}
          </div>
          
          <div className="goodsName">
            상품 : {boards.goodsName}
          </div>

          <div className="goodsPrice">
            가격 : {boards.price} 원
          </div>

          <div className="goodsWriter">
            판매자 : {boards.writer}
          </div>
          
          <div className="goodsText">
          {boards.content}
          </div>

          <div className="goodsBtn">
            <span className="zzimBtn">
              <button class="btn btn-primary" type="submit" onClick={wishCountHandler}>찜 하기</button>
            </span>
            <button class="btn btn-primary" type="submit">판매자와 대화</button>
          </div>
        </div>
      </div>
    );
};

export default Goods;

This is api server

enter image description here

and this is my object data structure enter image description here

1 Answers

I fixed it Instead of writing your own state as it is in setState, you need to get the prev value and fix it. And when making an async request, be sure to use async-await, and receive response by using then query for getting your request successfully.

import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
import "./goods.css";

const Goods  = (props) => {
  const [boards, setBoards] = useState({});
  const [images, setImages] = useState([]);
  const {id}  = useParams();
  const [isWishAdd, setIsWishAdd] = useState(false);
  const [wishCount, setWishCount] = useState(0); 

  const wishCountHandler = async () => {
    if (!isWishAdd) {
      setWishCount(prev => prev +1)
      await fetch(`https://27.96.131.85:8443/api/likeBoards/${boards.id}`, {
        credentials: 'include',
        method: "POST",
        body: JSON.stringify({
         liked: true
        }),
      })
      alert("찜 목록에 추가되었습니다.")
      console.log(boards)
      console.log("count+1")
    } else  {
      setWishCount(prev => prev -1)
      await fetch(`https://27.96.131.85:8443/api/likeBoards/${boards.id}`, {
        credentials: 'include',
        method: "DELETE",
        body: JSON.stringify({
          liked: false
        })
      })
      alert("찜 목록에서 삭제되었습니다.")
      console.log(boards)
      console.log("count-1")
    }
    setIsWishAdd(prev => !prev);
  }    
  

  useEffect(() => {
    (async function () {
      await axios.get(`https://27.96.131.85:8443/api/boards/${id}`, {
        withCredentials: true,
      }).then((res)=> {
        console.log(res);
        setBoards(res.data);
        setImages(res.data.boardImages);
      });

      // 게시글 정보 state에 저장

    })();
  }, []);

    return(
      <div id="goods">
        <p className="goodsTitle">상품 정보</p>
        <div className="images_container">
          {
            images.map((images) => {
              return (
                <img className="goodsImages"
                src={`https://27.96.131.85:8443/api/images/${images.id}`} />
              )
            })
          }
        </div>
       
        <div className="goodsContext">  
          <div className="goodsBoardTitle">
            {boards.title}
          </div>
          
          <div className="goodsName">
            상품 : {boards.goodsName}
          </div>

          <div className="goodsPrice">
            가격 : {boards.price} 원
          </div>

          <div className="goodsWriter">
            판매자 : {boards.writer}
          </div>
          
          <div className="goodsText">
          {boards.content}
          </div>

          <div className="goodsBtn">
            <span className="zzimBtn">
              <button class="btn btn-primary" type="submit" onClick={wishCountHandler}>찜 하기</button>
            </span>
            <button class="btn btn-primary" type="submit">판매자와 대화</button>
          </div>
        </div>
      </div>
    );
};

export default Goods;
Related