잘 되고 있지만, 여기서 무슨 일이 일어나고 있는 지 조금 더 알아보자.
src/routes/edit.jsx
파일을 보자.
<input
placeholder="First"
aria-label="First name"
type="text"
name="first"
defaultValue={contact.first}
/>
<input
placeholder="Last"
aria-label="Last name"
type="text"
name="last"
defaultValue={contact.last}
/>
자바스크립트가 없으면 form이 전송될 때, 브라우저는 FormData
객체를 만들어서 request의 body에 붙여서 서버에 전송한다.
앞에서 배웠듯 react router는 서버로 전송하는 대신 action으로 전송한다.
물론 FormData
도 마찬가지다.
form의 각 필드에 액세스하려면 formData.get(name)
와 같이 사용한다.
예를 들어 위 코드의 input 필드에 액세스하려면 다음과 같이 사용한다.
export async function action({ request, params }) {
const formData = await request.formData();
const firstName = formData.get("first");
const lastName = formData.get("last");
// ...
}
Object.fromEntries
를 사용해서 하나의 객체로 모은다.
이렇게 만들어진 객체가 바로 업데이트 대상이 되는 데이터이자, updateContact
함수로 전달할 데이터이다.
const updates = Object.fromEntries(formData);
updates.first; // "Some"
updates.last; // "Name"
참고로, 위에서 사용한 request
, request.formData
, Object.fromEntries
는 모두 react router에서 제공하는 것이 아닌 웹 플래폼에서 제공하는 것이다.
action이 끝난 후, redirect
한다.
export async function action({ request, params }) {
const formData = await request.formData();
const updates = Object.fromEntries(formData);
await updateContact(params.contactId, updates);
return redirect(`/contacts/${params.contactId}`);
}
Loaders 와 actions는 Response
객체를 리턴할 수 있다.
Request
을 받으니 Response
를 반환하는 게 자연스럽다.
redirect
는 앱의 location이 변경되었다는 걸 알려주는 Response를 더 쉽게 반환하도록 만들어준다.
import { redirect } from "react-router-dom";
const loader = async () => {
const user = await getUser();
if (!user) {
return redirect("/login");
}
return null;
};
위의 코드는 아래의 코드의 shortcut 버전이라 볼 수 있다.
new Response("", {
status: 302,
headers: {
Location: someUrl,
},
});
출처 : 리액트 라우터 공식 홈페이지➡️