-
React RestAPI - 2Front-End/React 2024. 9. 3. 21:10728x90반응형
React RestAPI - 2
앞 장에서는 GET 방식만 다뤘지만 이제 나머지 HTTP 메서드도 다뤄보겠다.
1. PUT
화면
지금 화면 상으로는 문제 없이 동작하는 것 같지만, 새로고침하면 체크박스가 해제된 상태로 렌더링된다.
당연하지만 지금 db에 값을 바꾼 것이 아니라 state만 바꿔주고 있기 때문이다.
그래서 실제로 체크할 때마다 db에 값이 변동되게 해보자.
Word.js
function toggleDone() { fetch(`http://localhost:3001/words/${word.id}`, { method : 'PUT', headers : { 'Content-Type' : 'application.json' }, body : JSON.stringify({ ...word, isDone : !isDone }) }) .then(res => { if (res.ok) { setIsDone(!isDone); } }) }
setIsDone(!isDone); 한 줄만 있었던 toggleDone() 함수를 이렇게 수정했다.
이제 실제로 데이터가 변경되고, res.ok를 통해 변경이 잘 된 것을 확인하면 state도 수정한다.
이제 새로고침해도 내가 마지막에 두었던 상태로 렌더링된다.
2. DELETE
수정을 했으니 삭제도 해보자.
function del() { if (window.confirm('삭제 하시겠습니까?')){ fetch(`http://localhost:3001/words/${word.id}`, { method : 'DELETE' }) } }
<button className="btn_del" onClick={del}>삭제</button>
실수로 삭제하기 전에 알림창을 통해 확인 정도만 시켜주고 있다.
그런데 이렇게 하면, 삭제를 수락했을 때 새로고침을 해야지만 삭제된 화면을 볼 수 있다.
그래서 삭제가 되면 컴포넌트를 다시 렌더링하게 만들어보자.
앞에서 다루었는데, 리액트는 state에 변동사항이 생기면 컴포넌트를 다시 렌더링하니까,
단어를 state에 등록하고 삭제를 하고나서 단어의 state에 변동을 주자.
export default function Word({ word:w }) { const [word, setWord] = useState(w)
일단 state에 word를 등록했다.
이런 문법도 가능하길래 그냥 가져와봤다. 이제 word를 변동시키는 것도 작성해보자.
function del() { if (window.confirm('삭제 하시겠습니까?')){ fetch(`http://localhost:3001/words/${word.id}`, { method : 'DELETE' }) .then(res => { if (res.ok) { setWord({ id: 0}); } }); } } if (word.id === 0){ return null; } return ( <> <tr className={isDone ? 'off' : ''}> <td> <input type="checkbox" checked={isDone} onChange={toggleDone}/> </td> <td> {word.eng} </td> <td> {isShow && word.kor} </td> <td> <button onClick={toggleShow}>뜻보기</button> <button className="btn_del" onClick={del}>삭제</button> </td> </tr> </> )
삭제가 정상적으로 되면 setWord를 통해 state에 변동을 주고,
아래에서 조건문을 통해 null을 반환하고 있다.
null을 반환하는 것 자체에 큰 의미가 있는 것은 아니고,
이렇게 return문을 작성해주면 아래의 JSX가 리턴되지 않는 것이 의의다.
3. PUT
조회 수정 삭제를 했으니 마지막은 등록이다.
등록용 페이지를 먼저 만들어주자.
CreateWord.js
export default function CreateWord() { const days = useFetch("http://localhost:3001/days"); return ( <form> <div className="input_area"> <label>단어</label> <input type="text" placeholder="example"/> </div> <div className="input_area"> <label>뜻</label> <input type="text" placeholder="예시"/> </div> <div className="input_area"> <label>날짜</label> <select> { days.map(day => ( <option key={day.id} value={day.day}> {day.day} </option> )) } </select> </div> <button>저장</button> </form> ); }
App.js의 return문에 추가
<Route path="/create_word" element={<CreateWord></CreateWord>}> </Route>
화면
이렇게 생겼다.
이 상태에서 저장을 누르면 새로고침이 되버리는데 내 마음대로 할 수 있게 코드를 바꿔주겠다.
먼저 제출을 막기 위해 다음 코드 추가
function onSubmit(e) { e.preventDefault(); }
<form onSubmit={onSubmit}>
그리고 각 값에 접근할 수 있게 만들어보자.
const engRef = useRef(null); const korRef = useRef(null); const dayRef = useRef(null);
<input type="text" placeholder="example" ref={engRef}/> <input type="text" placeholder="예시" ref={korRef}/> <select ref={dayRef}>
각 입력태그에 ref 속성을 추가해주었다.
이러면 렌더링 결과가 DOM에 영향을 끼친 후에 해당 값에 접근할 수 있다.
onSubmit()에 fetch() 추가
function onSubmit(e) { e.preventDefault(); fetch(`http://localhost:3001/words`, { method : 'POST', headers : { 'Content-Type' : 'application.json' }, body : JSON.stringify({ day : dayRef.current.value, eng : engRef.current.value, kor : korRef.current.value, isDone : false }) }) .then(res => { if (res.ok) { alert("생성이 완료되었습니다."); } }); }
정상적으로 작동한다.
하지만 전에 배웠던 PRG 흐름으로 작성하면 더 좋을 것 같다.
4. navigate
예전엔 history였는데 이게 나중에 바뀌었다.
const days = useFetch("http://localhost:3001/days"); const navigate = useNavigate(); function onSubmit(e) { e.preventDefault(); fetch(`http://localhost:3001/words`, { method : 'POST', headers : { 'Content-Type' : 'application.json' }, body : JSON.stringify({ day : dayRef.current.value, eng : engRef.current.value, kor : korRef.current.value, isDone : false }) }) .then(res => { if (res.ok) { alert("생성이 완료되었습니다."); navigate(`/day/${dayRef.current.value}`); } }); }
같은 원리로, 날짜 등록도 해보자
CreateDay.js
export default function CreateDay() { const days = useFetch("http://localhost:3001/days"); const navigate = useNavigate(); function addDay(e) { fetch(`http://localhost:3001/days/`, { method : 'POST', headers : { 'Content-Type' : 'application.json' }, body : JSON.stringify({ day : days.length + 1 }) }) .then(res => { if (res.ok) { alert("생성이 완료되었습니다."); navigate(`/`); } }); } return ( <div> <h3>현재 일수 : {days.length}일</h3> <button onClick={addDay}>Day 추가</button> </div> ) }
화면
기능도 모두 정상작동한다.
728x90반응형'Front-End > React' 카테고리의 다른 글
React 스프링부트와 리액트 연동하기 (3) 2024.09.19 React RestAPI - 1 (2) 2024.09.03 React 라우터 (1) 2024.09.02 React 더미 데이터 생성, map() 반복 (2) 2024.08.31 React 각 컴포넌트 별 CSS 적용 (0) 2024.08.31