ํ ์คํธ ์ฝ๋ ์์ฑ
๊ตฌ๋งค ํ์ด์ง์๋ ์ธ ๊ฐ์ง ์์ญ์ด ์๋ค :
<ShippingInformationForm />- ๋ฐฐ์ก ์ ๋ณด ์ ๋ ฅ
- API๋ฅผ ํตํด ์ฟ ํฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋ ๋๋ง
- ๊ฐ ํ๋๋ณ ์ ํจ์ฑ ๊ฒ์ฆ
<ItemList />- ์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธด ์ํ๊ณผ ๊ฐ๊ฒฉ ์ ๋ณด ๋ ธ์ถ
<Payment />- ์ด ์ํ ๊ธ์ก, ํ ์ธ ์ฟ ํฐ, ์ด ๊ฒฐ์ ๊ธ์ก ๋ฑ ๊ฒฐ์ ์ ๋ณด๋ฅผ ๊ณ์ฐํ์ฌ ๋ ธ์ถ
- ๊ฒฐ์ ๋ฐฉ๋ฒ ์ ํ
const { resetCart } = useCartStore(state => pick(state, 'resetCart'));
const { user } = useUserStore(state => pick(state, 'user'));
//...
const methods = useForm({
defaultValues: {
name: user?.name ?? '',
address: '',
phone: '',
requests: '',
coupon: NO_COUPON_ID,
payment: 'accountTransfer',
},
});
const { handleSubmit } = methods;
return (
<FormProvider {...methods}>
//...
<ShippingInformationForm />
<ItemList />
<Payment />
//...
<Button
variant="contained"
size="large"
onClick={handleClickPurchase}
>
๊ตฌ๋งคํ๊ธฐ
</Button>
</FormProvider>
);
ShippingInformationForm
ShippingInformationForm์ ๊ฐ ์
๋ ฅ์ฐฝ๋ง๋ค useFormContext()๋ก FormProvider์ ์ปจํ
์คํธ์ ์ฐ๋ํ์ฌ ์
๋ ฅ๊ฐ ์ ํจ์ฑ ๊ฒ์ฆ์ ํ๋ค.
const NameTableRow = () => {
const {
register,
formState: { errors },
} = useFormContext();
return (
//...
<TextField
{...register('name', { required: '์ด๋ฆ์ ์
๋ ฅํ์ธ์' })}
type="input"
error={!!errors?.name}
helperText={errors?.name?.message}
size="small"
placeholder="์ด๋ฆ์ ์
๋ ฅํ์ธ์"
/>
//...
);
};
๊ทธ๋์ ํ ์คํธ๋ฅผ ์งํํ ๋ ์ด ์ปจํ ์คํธ ํ๋ก๋ฐ์ด๋ ์ปดํฌ๋ํธ๋ ๋ชจํน์ ํด์ผํ๋ค.
//ShippingINformationForm.spec.jsx
const TestForm = props => {
const methods = useForm({
defaultValues: {
name: '',
address: '',
phone: '',
requests: '',
coupon: NO_COUPON_ID,
...props,
},
});
return (
<FormProvider {...methods}>
<ShippingInformationForm />
<button type="button" onClick={methods.handleSubmit(() => {})}>
ํ
์คํธ ๋ฒํผ
</button>
</FormProvider>
);
};
ItemList
์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธด ์ํ๋ค์ ๊ฐ์์ ์ด์ก์ ๋ณด์ฌ์ฃผ๊ธฐ๋ง ํ๋ ์ปดํฌ๋ํธ๋ผ ๊ฒ์ฆํ ๊ฒ ๊ฐ๋จํ๋ค. cart ์คํ ์ด๋ง ๋ชจํนํด์ ์ํ ๊ฐ์์ ๊ธ์ก์ด ๋ง๋์ง๋ง ๊ฒ์ฆํ๋ฉด ๋๋ค.
//ItemList.spec.jsx
beforeEach(() => {
mockUseCartStore({
cart: {
6: {
id: 6,
title: 'Handmade Cotton Fish',
price: 100,
description:
//...
Payment
์ด ์ปดํฌ๋ํธ๋ <FormProvider>์ ์ปจํ
์คํธ์ ์์กดํ๊ธฐ ๋๋ฌธ์ ํ
์คํธ๋ฅผ ์งํํ ๋ ํ๋ก๋ฐ์ด๋์ ์ปจํ
์คํธ๋ฅผ ํฌํจํด ๋ชจํนํด์ผ ํ๋ค.
//Payment.spec.jsx
const TestPayment = (props = {}) => {
const methods = useForm({
defaultValues: {
name: 'leejaesung',
address: '',
phone: '',
requests: '',
coupon: NO_COUPON_ID,
...props,
},
});
return (
<FormProvider {...methods}>
<Payment />
</FormProvider>
);
};
ํตํฉ ํ ์คํธ์ ํ๊ณ
์์ ํตํฉํ ์คํธ๋ฅผ ๋ณด๋ฉด ๊ตฌ๋งค ํ์ด์ง์ ์๋ ๋๋ฉ์ธ๋ณ๋ก ์ธ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ํ ์คํธ ํ๊ณ ์๋ค. ๊ฐ ํญ๋ชฉ์ ์ ๋ ฅ๊ฐ ์ ํจ์ฑ ๊ฒ์ฆ์ด ์ ์ด๋ฃจ์ด์ง๋์ง, ์ฟ ํฐ ๋ชฉ๋ก์ด ์ ๋๋ก ์ถ๋ ฅ๋๋์ง, ์ฅ๋ฐ๊ตฌ๋์ ๋ฌผํ๊ณผ ์ด์ก์ด ๋ง๊ฒ ๋์ค๋์ง ๋ฑ. ๊ทธ๋ฌ๋ ์ด ๋ชจ๋ ๊ฒ์ฆ์ ํต๊ณผํ๋ค๋๊ฒ๊ณผ ์ํ ๊ตฌ๋งค ํ๋ก์ธ์ค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋๊ฒ์ ๋ค๋ฅธ ๋ฌธ์ ๋ค.
์ํ ๊ตฌ๋งค ํ๋ก์ธ์ค์์ ๊ฒฐ๊ตญ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ ๋ฐฐ์ก ์ ๋ณด ์ ๋ ฅ ํ๋์ ๊ฒฐ์ ๊ธ์ก ์ ๋ณด, ๊ฒฐ์ ์๋จ ๋ฑ์ ๋ํ ์ ๋ณด๋ฅผ API์ ์ ๋ฌํ์ฌ ํธ์ถํ์ ๋ ์ฃผ๋ฌธ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋ง๋ค์ด์ง๊ณ ์ดํ์ ๊ฒฐ์ ์ฑ๊ณต๊ณผ ์คํจ์ ๋ฐ๋ฅธ ํ๋ฆ์ด ์ ๋์ํ๋์ง ํ์ธํ๋ ๊ฒ์ด๋ค.
๊ตฌ๋งค ํ์ด์ง ์ ์ฒด๋ฅผ ๋์์ผ๋ก ํตํฉ ํ ์คํธ๋ฅผ ์์ฑํ๋ค๋ฉด?
๊ทธ๋ฌ๊ธฐ ์ํด์๋ cart ์คํ ์ด, user ์คํ ์ด์ ๋ํ ๋ชจํน๊ณผ ์ฟ ํฐ ๋ฆฌ์คํธ api์ ๊ตฌ๋งคํ๊ธฐ api ๋ชจ๋์ ๋ํ ๋ชจํน์ด ํ์ํ๊ฒ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ตฌ๋งค ์ฑ๊ณต, ์คํจ ์ฌ๋ถ๋ ์ด์ฐจํผ ๋ชจํน์ ์์กดํด์ผ ํ๋ค.
ํตํฉ ํ ์คํธ๋ ์ด๋ ๊ฒ ํฐ ๊ท๋ชจ์, ์ ์ฒด ํ๋ก์ธ์ค(์ํฌํ๋ก์ฐ)๋ฅผ ๊ฒ์ฆํ๋๋ฐ ์ ํจํ ํ ์คํธ๊ฐ ์๋๋ค. ํตํฉ ํ ์คํธ๋ ๋๋ฉ์ธ ๋จ์์ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ์ปดํฌ๋ํธ๊ฐ์ ์ํธ์์ฉ์ ๊ฒ์ฆํ๋๋ฐ ๋งค์ฐ ํจ์จ์ ์ด๋ค.
