home강의 홈으로
Section 4. GraphQL 클라이언트 만들어보기
Lesson 2. Query와 Mutation을 사용하여 웹페이지 만들기
2. Query와 Mutation을 사용하여 웹페이지 만들기
모듈 로드
// ...
import { useState } from 'react';
import { useQuery, useMutation, gql } from '@apollo/client'
// ...
state 준비
// ...
const [contentId, setContentId] = useState(0)
const [inputs, setInputs] = useState({
manager: '',
office: '',
extension_number: '',
mascot: '',
cleaning_duty: '',
project: ''
})
// ...
팀 목록 받아오기
쿼리 작성
// ...
const GET_TEAMS = gql`
query GetTeams {
teams {
id
manager
members {
id
first_name
last_name
role
}
}
}
`;
// ...
목록 받아와 보여주기 함수
// ...
function AsideItems () {
const roleIcons = {
developer: '💻',
designer: '🎨',
planner: '📝'
}
const { loading, error, data, refetch } = useQuery(GET_TEAMS);
if (loading) return <p className="loading">Loading...</p>
if (error) return <p className="error">Error :(</p>
return (
<ul>
{data.teams.map(({id, manager, members}) => {
return (
<li key={id}>
<span className="teamItemTitle" onClick={() => {setContentId(id)}}>
Team {id} : {manager}'s
</span>
<ul className="teamMembers">
{members.map(({id, first_name, last_name, role}) => {
return (
<li key={id}>
{roleIcons[role]} {first_name} {last_name}
</li>
)
})}
</ul>
</li>
)
})}
</ul>
)
}
// ...
항목 받아오기
쿼리 작성
// ...
const GET_TEAM = gql`
query GetTeam($id: ID!) {
team(id: $id) {
id
manager
office
extension_number
mascot
cleaning_duty
project
}
}
`;
// ...
항목 받아와 보여주기 함수
// ...
function MainContents () {
const { loading, error } = useQuery(GET_TEAM, {
variables: {id: contentId},
onCompleted: (data) => {
if (contentId === 0) {
setInputs({
manager: '',
office: '',
extension_number: '',
mascot: '',
cleaning_duty: '',
project: ''
})
} else {
setInputs({
manager: data.team.manager,
office: data.team.office,
extension_number: data.team.extension_number,
mascot: data.team.mascot,
cleaning_duty: data.team.cleaning_duty,
project: data.team.project
})
}
}
});
if (loading) return <p className="loading">Loading...</p>
if (error) return <p className="error">Error :(</p>
function handleChange(e) {
const { name, value } = e.target
setInputs({
...inputs,
[name]: value
})
}
return (
<div className="inputContainer">
<table>
<tbody>
{contentId !== 0 && (
<tr>
<td>Id</td>
<td>{contentId}</td>
</tr>
)}
<tr>
<td>Manager</td>
<td><input type="text" name="manager" value={inputs.manager} onChange={handleChange}/></td>
</tr>
<tr>
<td>Office</td>
<td><input type="text" name="office" value={inputs.office} onChange={handleChange}/></td>
</tr>
<tr>
<td>Extension Number</td>
<td><input type="text" name="extension_number" value={inputs.extension_number} onChange={handleChange}/></td>
</tr>
<tr>
<td>Mascot</td>
<td><input type="text" name="mascot" value={inputs.mascot} onChange={handleChange}/></td>
</tr>
<tr>
<td>Cleaning Duty</td>
<td><input type="text" name="cleaning_duty" value={inputs.cleaning_duty} onChange={handleChange}/></td>
</tr>
<tr>
<td>Project</td>
<td><input type="text" name="project" value={inputs.project} onChange={handleChange}/></td>
</tr>
</tbody>
</table>
{contentId === 0 ?
(<div className="buttons">
<button onClick={() => {}}>Submit</button>
</div>
) : (
<div className="buttons">
<button onClick={() => {}}>Modify</button>
<button onClick={() => {}}>Delete</button>
<button onClick={() => {setContentId(0)}}>New</button>
</div>
)}
</div>
)
}
// ...
항목 삭제하기
쿼리 & 함수 작성
// ...
const DELETE_TEAM = gql`
mutation DeleteTeam($id: ID!) {
deleteTeam(id: $id) {
id
}
}
`
// ...
function execDeleteTeam () {
if (window.confirm('이 항목을 삭제하시겠습니까?')) {
deleteTeam({variables: {id: contentId}})
}
}
const [deleteTeam] = useMutation(
DELETE_TEAM, { onCompleted: deleteTeamCompleted })
function deleteTeamCompleted (data) {
console.log(data.deleteTeam)
alert(`${data.deleteTeam.id} 항목이 삭제되었습니다.`)
setContentId(0)
}
// ...
버튼에 적용
// ...
<button onClick={execDeleteTeam}>Delete</button>
// ...
⭐ 수정된 데이터 다시 로드
// ...
let refetchTeams
// ...
refetchTeams = refetch
// ...
alert(`${data.deleteTeam.id} 항목이 삭제되었습니다.`)
refetchTeams()
// ...
항목 수정하기
// ...
const EDIT_TEAM = gql`
mutation EditTeam($id: ID!, $input: PostTeamInput!) {
editTeam(id: $id, input: $input) {
id,
manager,
office,
extension_number,
mascot,
cleaning_duty,
project
}
}
`
// ...
function execEditTeam () {
editTeam({
variables: {
id: contentId,
input: inputs }
})
}
const [editTeam] = useMutation(
EDIT_TEAM, { onCompleted: editTeamCompleted })
function editTeamCompleted (data) {
console.log(data.editTeam)
alert(`${data.editTeam.id} 항목이 수정되었습니다.`)
refetchTeams()
}
// ...
<button onClick={execEditTeam}>Modify</button>
// ...
항목 추가하기
// ...
const POST_TEAM = gql`
mutation PostTeam($input: PostTeamInput!) {
postTeam(input: $input) {
id
manager
office
extension_number
mascot
cleaning_duty
project
}
}
`
// ...
function execPostTeam () {
postTeam({
variables: { input: inputs }})
}
const [postTeam] = useMutation(
POST_TEAM, { onCompleted: postTeamCompleted })
function postTeamCompleted (data) {
console.log(data.postTeam)
alert(`${data.postTeam.id} 항목이 생성되었습니다.`)
refetchTeams()
setContentId(0)
}
// ...
<button onClick={execPostTeam}>Submit</button>
// ...
🤔얄코에게 질문하기질문은 반.드.시 이리로 보내주세요! ( 강의사이트 질문기능 ✖ )
🛑질문 전 필독!!
- 구글링을 먼저 해 주세요. 들어오는 질문의 절반 이상은 구글에 검색해 보면 1분 이내로 답을 찾을 수 있는 내용들입니다.
- 오류 메시지가 있을 경우 이를 구글에 복붙해서 검색해보면 대부분 짧은 시간 내 해결방법을 찾을 수 있습니다.
- 강의 페이지에 추가사항 등 놓친 부분이 없는지 확인해주세요. 자주 들어오는 질문은 페이지에 추가사항으로 업데이트됩니다.
- "유료파트의 강의페이지는 어디 있나요?" - 각 영상의 시작부분 검은 화면마다 해당 챕터의 강의페이지 링크가 있습니다.
- 질문을 보내주실 때는 문제가 어떻게 발생했고 어떤 상황인지 등을 구체적으로 적어주세요. 스크린샷을 첨부해주시면 더욱 좋습니다.