Request & Response
클라이언트는 서버에게 요청을 보냅니다.
"회원가입 시켜줘" , "게시물 생성해줘" 등등
이때 API라는 체계를 이용하여 클라이언트와 서버간에 요청과 응답을 주고 받습니다.
그 중에서도 더 체계적으로 API를 관리하기 위해 REST API가 등장했습니다.
REST API는 HTTP프로토콜을 사용해 통신하며, HTTP 메서드로 요청을 표현한다는 특징이 있습니다.
요청을 보낼 때는 보낼 정확한 서버 주소를 알아야 합니다.
서버주소는 '서버주소/A'와 같이 구성되어 있습니다. 서버주소는 말 그대로 서버 컴퓨터가 위치한 곳의 주소이고, 슬래시 뒤의 A라는 곳에는 원하는 요청 기능을 적어줍니다.
예를 들면 서버주소/signin 은 로그인 기능을 수행하고 서버주소/signup은 회원가입 기능을 수행하는 식입니다.
fetch
js 비동기 함수입니다.
fetch().then().then()
- fetch() : 요청지 주소, method headers 등 요청정보, 데이터정보(body)
- then() : 첫번째 then. 받을 데이터 형태의 빈깡통으로 세팅, 나머지 랜러딩을 계속 진행
- then() : 두번째 then. 실제 데이터가 담기는 곳, 렌더링 완료 후 두번째 then에 데이터가 있으면 다시 랜더링이 일어남.
예시입니다. url에 주소를 넣어주면 됩니다.
import { useEffect, useState } from "react";
export default function useFetch(url)
{
const [data, setData] = useState([]);
useEffect(()=>{
fetch(url)
.then(res=>{
return res.json()
})
.then(data=>{
setData(data);
})
},[url]);
return data;
}
fetch() 기본은 get이기 때문에 아무것도 작성하지 않아도 get으로 호출했는데,
get이외의 경우에는 fetch()함수에 method 정보를 인자로 넘겨줘야합니다.
CRUD
Delete
Delete = DELETE
delete는 정보를 지우는 요청입니다.
아래의 json 데이터에서 데이터를 선택하여 삭제해보겠습니다. fetch를 이용하겠습니다.
위의 json파일에서 데이터를 삭제하기 위해 데이터의 각각에 있는 id를 이용해 삭제를 할 것 입니다.
http://localhost:3001/words/6
와 같이 주소를 입력하면 해당 데이터만 나오게 됩니다.
따라서 fetch에 url에 위의 주소를 넣어주면 됩니다.
먼저 데이터를 화면에 표시해주고 삭제 버튼을 만들어줍니다.
그리고 삭제버튼의 onClick이벤트로 함수를 적어줍니다. fetch의 두번째인자에 method와 body를 보내줍니다.
word라는 useState에 단어들이 담겨져 있습니다.
then에서 삭제가 완료되었으면 State를 변경해주어 페이지를 리렌더링해줍니다.
const [word,setWord] = useState(props.word)
function del(){
if(window.confirm('삭제 하시겠습니까?')){
fetch(`http://localhost:3001/words/${word.id}`, {
method : 'DELETE',
}).then(res=>{
if(res.ok){
setWord({id:0});
}
})
}
}
....
<button onClick={del} class="btn_del">삭제</button>
아래에서 mouse단어를 삭제해보겠습니다.
Post
아래와 같은 입력폼에서 저장버튼을 누르면 데이터를 서버로 전송해보겠습니다.
여기서 알아야할 개념이 useRef입니다.
리액트에서 redux 또는 useState를 통해 참조하는 값이 변경되면 해당 값을 참조하는 컴포넌트를 리랜더링시킵니다. 하지만 참조값이 변경되더라도 리랜더링이 필요하지 않을 경우 useRef를 사용하여 적절한 대안으로 삼을 수 있습니다.
- useRef를 사용하면 참조하는 값이 변경되더라도 컴포넌트의 리랜더링이 발생하지 않습니다.
- redux나 useState를 통해 다른 참조하는 값이 변경되어 컴포넌트가 리랜더링되더라도 useRef가 참조하고 있는 값은 변경되지 않고 유지됩니다.
그리고 DOM에 직접 접근하여 ref를 통해 해당 태그의 className값을 가져오거나 style을 변경하는 등 의 작업이 가능합니다.
마찬가지로 fetch를 이용하여 url을 넘겨주고 두번째 인수로 method와 body를 넘겨줍니다.
body에 입력폼에서 담긴 데이터를 보내주면됩니다. current.value를 통해 값에 접근할 수 있습니다.
const engRef = useRef(null);
const korRef = useRef(null);
const dayRef = useRef(null);
function onSubmit(e) {
e.preventDefault();
if (!isLoading) {
setIsLoading(true);
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}`)
setIsLoading(false);
}
});
}
}
아래와 같이 입력하고 저장을 눌러보면
단어가 생성된걸 볼 수 있습니다.
Create의 전체코드입니다.
추가로 저장버튼을 누를 때 한번만 클릭되게 isLoading이라는 useState를 만들어줬습니다.
import { useRef, useState } from "react";
import useFetch from "../hooks/useFetch"
import { useNavigate } from "react-router-dom";
export default function CreateWord() {
const days = useFetch("http://localhost:3001/days");
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);
const engRef = useRef(null);
const korRef = useRef(null);
const dayRef = useRef(null);
function onSubmit(e) {
e.preventDefault();
if (!isLoading) {
setIsLoading(true);
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}`)
setIsLoading(false);
}
});
}
}
return (
<form onSubmit={onSubmit}>
<div className="input_area">
<label>Eng</label>
<input type="text" placeholder="computer" ref={engRef} />
</div>
<div className="input_area">
<label>Kor</label>
<input type="text" placeholder="컴퓨터" ref={korRef} />
</div>
<div className="input_area">
<label>Day</label>
<select ref={dayRef}>
{days.map(day => (
<option key={day.id}>{day.day}</option>
))}
</select>
</div>
<button style={{opacity: isLoading ? 0.3 : 1,}}>{isLoading ? "Saving...": "저장"}</button>
</form>
)
}
'프론트엔드 > react' 카테고리의 다른 글
React - axios(post) 서버와 통신하기(로그인,게시물작성(FormData)) (0) | 2023.09.08 |
---|---|
React - window.location.replace() (0) | 2023.09.07 |
Rest API , 리액트에서 REST API 구축 (1) | 2023.09.04 |
react - state 변경함수 사용할 때 주의점 : async (0) | 2023.08.07 |
React - 성능개선(useTransition, useDeferredValue) (0) | 2023.08.07 |