728x90
next.js 13버전 때 학습내용 정리 문서로 현재와 다름 주의
Server Actions
React Actions 위에 구축된 알파 기능.
서버측 데이터 변형, 클라이언트 측 코드 감소 및 향상된 양식을 가능하게 함
// app/add-to-cart.js
import { cookies } from 'next/headers';
export default function AddToCart({ productId }) {
async function addItem(data) {
'use server';
const cartId = cookies().get('cartId')?.value;
await saveToDb({ cartId, data });
}
return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
);
}
Rule
아래처럼 설정하여 활성화
module.exports = {
experimental: {
serverActions: true,
},
};
만들기
'use server’를 비동기 함수에 선언하여 서버작업을 만듬.
이 함수에는 직렬화 가능한 인수와 반환값이 있어야함.
async function myAction() {
'use server';
// ...
}
최상위 지시문 사용 가능. export가 많은 action 파일
'use server';
export async function myAction() {
// ...
}
Invocation (호출)
다음 방법을 사용하여 서버 작업을 호출함
- action 사용 : React의 action prop를 사용하여
<form>
에서 서버 액션을 호출할 수 있음 - formAction 사용 : React의 formAction prop를 사용하면
<form>
에서<button>
,<input type="submit">
,<input type="image">
를 처리할 수 있음. - startTransition을 사용한 사용자 정의 호출 : startTransition을 사용하여 action 또는 formAction을 사용하지 않고 서버 액션을 호출함. 이 방법은 프로그레시브 향상을 비활성화함.
action
export default function AddToCart({ productId }) {
async function addItem(data) {
'use server';
const cartId = cookies().get('cartId')?.value;
await saveToDb({ cartId, data });
}
return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
);
}
액션은 html의 액션과 유사함.
formAction
export default function Form() {
async function handleSubmit() {
'use server';
// ...
}
async function submitImage() {
'use server';
// ...
}
return (
<form action={handleSubmit}>
<input type="text" name="name" />
<input type="image" formAction={submitImage} />
<button type="submit">Submit</button>
</form>
);
}
formAction은 html의 기본 formAction임. React에서 이 속성에 함수를 전달할 수 있음.
startTransition을 사용한 사용자 정의 호출
useTransition 훅에서 제공되는 startTransition으로 사용할 수 있음.
form, button, input에서 서버 액션을 쓰고 싶은 경우 유용함.
// app/_components/ex-client-component.js
'use client';
import { useTransition } from 'react';
import { addItem } from '../_actions';
function ExampleClientComponent({ id }) {
let [isPending, startTransition] = useTransition();
return (
<button onClick={() => startTransition(() => addItem(id))}>
Add To Cart
</button>
);
}
// app/_actions.js
'use server';
export async function addItem(id) {
await addItemToDb(id);
revalidatePath(`/product/${id}`);
}
startTransition을 사용하지 않는 사용자 정의 호출
서버 변형(redirect, revalidatePath, revalidateTag)을 수행하지 않는 경우 다른 함수처럼 함수를 직접 프로퍼티로 전달할 수 있음.
향상된 기능
useOptimistic
앱의 반응성을 높여 사용자 경험을 향상시키는 기술.
서버 액션이 호출되면 응답을 기다리지 않고 예상결과를 반영하여 UI가 업데이트 됨
'use client';
import { experimental_useOptimistic as useOptimistic } from 'react';
import { send } from './_actions.js';
export function Thread({ messages }) {
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessage) => [...state, { message: newMessage, sending: true }],
);
const formRef = useRef();
return (
<div>
{optimisticMessages.map((m) => (
<div>
{m.message}
{m.sending ? 'Sending...' : ''}
</div>
))}
<form
action={async (formData) => {
const message = formData.get('message');
formRef.current.reset();
addOptimisticMessage(message);
await send(message);
}}
ref={formRef}
>
<input type="text" name="message" />
</form>
</div>
);
}
useFormStatus
form에서 사용할 수 있고 pending 속성을 제공함.
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
function Submit() {
const { pending } = useFormStatus();
return (
<input
type="submit"
className={pending ? 'button-pending' : 'button-normal'}
disabled={pending}
>
Submit
</input>
);
}
프로그레시브 향상
프로그레시브 향상을 이용하면 js가 없거나 비활성화된 상태에서도 <form>
이 제대로 동작할 수 있음.
- 서버 액션이
<form>
에 직접 전달되는 경우 js가 비활성화되어 있어도 양식은 대화형으로 동작함 - 클라이언트 액션이
<form>
으로 전달되는 경우 form는 여전히 대화형이지만 form이 수화(?)될때 까지 대기열에 배치됨.
form은 선택적 하이드레이션으로 우선순위가 지정되므로 빠르게 처리됨
'use client';
import { useState } from 'react';
import { handleSubmit } from './_actions.js';
export default function ExampleClientComponent({ myAction }) {
const [input, setInput] = useState();
return (
<form action={handleSubmit} onChange={(e) => setInput(e.target.value)}>
{/* ... */}
</form>
);
}
'공부공부 > Next.js 공식문서' 카테고리의 다른 글
[next.js 공식문서] 19. Metadata (0) | 2024.03.03 |
---|---|
[next.js 공식문서] 18. Script Optimization (0) | 2024.03.03 |
[next.js 공식문서] 16. Revalidating (0) | 2024.03.01 |
[next.js 공식문서] 15. Caching (0) | 2024.03.01 |
[next.js 공식문서] 14. Fetching (0) | 2024.02.29 |