동아리(club) 프로트쪽(임시)

류한선·2024년 5월 14일

4차 프로젝트

목록 보기
34/53
'use client'

import { useState } from 'react';
import { useParams } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import api from "@/util/api";
import Link from 'next/link'

export default function ClubDetail() {
    const params = useParams();

    const getClub = async () => {
        return await api.get(`/clubs/${params.id}`)
            .then((response) => response.data.data.club);
    }

    const { isLoading: clubLoading, error: clubError, data: clubData } = useQuery({
        queryKey: ['club'],
        queryFn: getClub
    });

    if (clubError) {
        console.log(clubError);
    }

    if (clubLoading) {
        return <>Loading...</>;
    }

    if (clubData) {
        return (
            <>
                <h1>상세 {params.id}번</h1>
               
                <div>{clubData.clubName}</div>
                <Link href={`/club/${params.id}/edit`}>수정하기</Link>
                
            </>
        );
    }
}
'use client'

import Link from 'next/link';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import api from "@/util/api";

export default function Club() {
    const getClubs = async () => {
        try {
            const response = await api.get('/clubs');
            return response.data.data.club; // 수정된 부분
        } catch (error) {
            throw new Error('Failed to fetch clubs');
        }
    };
    

    const {isLoading, error, data} = useQuery({
        queryKey: ['clubs'],
        queryFn: getClubs
    });

    const deleteClub = async (id) => {
        await api.delete(`/clubs/${id}`);
    };

    const queryClient = useQueryClient();
    const mutation = useMutation({
        mutationFn: deleteClub,
        onSuccess: () => {
            queryClient.invalidateQueries({queryKey: ['clubs']});
        }
    });

    if (error) {
        console.error(error);
    }

    if (isLoading) {
        return <>Loading...</>;
    }
    
    if (error) {
        console.error(error);
        return <>Error occurred: {error.message}</>;
    }
    
    if (!data || data.length === 0) {
        return <>No data available</>;
    }
    
    return (
        <>
            <ul>
                
                {data.map((row) => (
                    <li key={row.id}>
                        {row.id} /{' '}
                        <Link href={`/club/${row.id}`}>{row.clubName}</Link> /{' '}
                        {row.author} / {row.createdDate}
                        <button onClick={() => mutation.mutate(row.id)}>
                            삭제
                        </button>
                    </li>
                ))}
            </ul>
            <Link href="/clubCreate">
                Club Create 페이지로 이동
            </Link>
        </>
    );
}
'use client'

import { useState } from 'react';
import api from '@/util/api';
import { useRouter } from 'next/navigation'; // 수정
import { useQueryClient } from '@tanstack/react-query';

export default function ClubCreate() {
    const router = useRouter();
    const [club, setClub] = useState({ clubName: ''});

    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            await api.post('/clubs', club);
            // 등록 성공 시, 이전 페이지로 이동하거나 사용자에게 알림을 제공할 수 있습니다.
            router.push('/club');
        } catch (error) {
            console.error('등록 중 에러:', error);
        }
    };

    const handleChange = (e) => {
        const { name, value } = e.target;
        setClub({ ...club, [name]: value });
    };

    return (
        <>
            <h3>글 등록</h3>
            <form onSubmit={handleSubmit}>
               
                <div>
                    <label>내용:</label>
                    <textarea name="clubName" value={club.clubName} onChange={handleChange} />
                </div>
                <button type="submit">등록</button>
            </form>
        </>
    );
}
'use client'

import api from "@/util/api"
import { useParams } from 'next/navigation'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation';

export default function ClubEdit() {
    const params = useParams()
    const router = useRouter();

    const [isLoading, setIsLoading] = useState(false)
    const [club, setClub] = useState({ clubName: '' })

    useEffect(() => {
        fetchClub()
    }, [])

    const fetchClub = async () => {
        try {
            const response = await api.get(`/clubs/${params.id}`)
            setClub(response.data.data.club)
            setIsLoading(true)
        } catch (error) {
            console.log(error)
        }
    }

    const handleSubmit = async (e) => {
        e.preventDefault()
        try {
            await api.patch(`/clubs/${params.id}`, club)
            router.push('/club');
        } catch (error) {
            console.log(error)
        }
    }

    const handleChange = (e) => {
        const { name, value } = e.target
        setClub({ ...club, [name]: value })
    }

    return (
        <>
            {isLoading ? (
                <>
                    <h1>수정페이지</h1>
                    <form onSubmit={handleSubmit}>
                        
                        <input
                            type="text"
                            name="clubName"
                            value={club.clubName}
                            onChange={handleChange}
                        />
                        <button type="submit">수정</button>
                    </form>
                </>
            ) : (
                <></>
            )}
        </>
    )
}

백엔드 코드를 살펴보니 API 응답이 클라이언트 코드에서 사용하는 예상 형식과 일치하는지 확인해야 합니다. 클라이언트 코드에서는 '/clubs' 엔드포인트에서 받은 데이터를 예상하고 있는데, 백엔드에서는 어떤 형태로 데이터를 반환하고 있는지를 확인해야 합니다.

예를 들어, 클라이언트 코드에서는 다음과 같이 예상하고 있습니다.

{
    "rsCode": {
        "code": "S-01",
        "keyWord": "Success"
    },
    "msg": "성공",
    "data": {
        "clubDto": {
            "id": 2,
            "clubName": "호ㅓㅏㅣ"
        }
    },
    "isSuccess": true
}

반면에 백엔드에서는 다음과 같은 형태로 응답을 보내고 있습니다.

{
    "rsCode": {
        "code": "S_01",
        "keyWord": "Success"
    },
    "msg": "성공",
    "data": {
        "club": [
            {
                "id": 2,
                "clubName": "호ㅓㅏㅣ"
            }
        ]
    }
}

클라이언트 코드에서는 'clubDto'를 예상하고 있는데, 실제로는 'club'로 데이터를 반환하고 있습니다. 이렇게 데이터 형식이 일치하지 않아 발생하는 오류로 보입니다. 클라이언트 코드에서는 'clubDto'를 사용하도록 수정해야 할 것 같습니다.

클라이언트 측에서 useQuery 훅을 사용하여 데이터를 가져오는 중에 문제가 발생하는 것으로 보입니다. 클라이언트 코드에서는 아마도 데이터를 data.data.clubs 형식으로 예상하고 있는데, 백엔드에서는 다른 형식으로 데이터를 반환하고 있습니다. 이를 확인하기 위해 백엔드에서 클라이언트로 보내는 데이터의 형식을 살펴보겠습니다.

백엔드에서는 ApiV1ClubController.getClubs() 메서드에서 클럽 목록을 가져오고 있습니다. 이 메서드는 ClubService.getList()를 통해 클럽 목록을 가져온 후에 ClubDto 형식으로 변환하여 반환합니다.

그리고 클럽 목록을 가져오는 ClubService.getList() 메서드에서는 ClubRepository.findAll()을 사용하여 클럽 엔티티의 모든 목록을 가져오고 있습니다.

따라서 클라이언트 코드에서는 클럽 목록을 가져올 때 백엔드에서 반환하는 데이터의 형식을 data.data.clubs로 예상하고 있는데, 실제로는 클럽 목록을 담고 있는 ClubDto의 리스트인 clubDtoList를 반환하고 있습니다.

따라서 클라이언트 코드에서는 다음과 같이 데이터를 가져와야 할 것으로 보입니다:

const getClubs = async () => {
    try {
        const response = await api.get('/clubs');
        return response.data.data.club; // 수정된 부분
    } catch (error) {
        throw new Error('Failed to fetch clubs');
    }
};

이렇게 수정하면 클라이언트 코드에서 예상하는 데이터 형식과 백엔드에서 실제로 반환하는 데이터 형식이 일치하게 됩니다. 이렇게 수정하면 클라이언트 코드에서 데이터를 정상적으로 처리할 수 있을 것입니다.

0개의 댓글