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> // ...

🤔얄코에게 질문하기질문은 반.드.시 이리로 보내주세요! ( 강의사이트 질문기능 ✖ )

강의에서 이해가 안 되거나 실습상 문제가 있는 부분,
설명이 잘못되었거나 미흡한 부분을 메일로 알려주세요!

답변드린 뒤 필요할 경우 본 페이지에
관련 내용을 추가/수정하도록 하겠습니다.

이메일 주소
yalco@yalco.kr
메일 제목 (반드시 아래 제목을 붙여넣어주세요!)
[질문] GraphQL과 Apollo 4-2

🛑질문 전 필독!!

  • 구글링을 먼저 해 주세요. 들어오는 질문의 절반 이상은 구글에 검색해 보면 1분 이내로 답을 찾을 수 있는 내용들입니다.
  • 오류 메시지가 있을 경우 이를 구글에 복붙해서 검색해보면 대부분 짧은 시간 내 해결방법을 찾을 수 있습니다.
  • 강의 페이지에 추가사항 등 놓친 부분이 없는지 확인해주세요. 자주 들어오는 질문은 페이지에 추가사항으로 업데이트됩니다.
  • "유료파트의 강의페이지는 어디 있나요?" - 각 영상의 시작부분 검은 화면마다 해당 챕터의 강의페이지 링크가 있습니다.
  • 질문을 보내주실 때는 문제가 어떻게 발생했고 어떤 상황인지 등을 구체적으로 적어주세요. 스크린샷을 첨부해주시면 더욱 좋습니다.
🌏 Why not change the world?