Reactãã«ãã¹ããŒãžãã©ãŒã ã§åŒ·åãã€æ®µéçãªæ€èšŒãå®çŸãuseFormStateããã¯ã掻çšããŠãã·ãŒã ã¬ã¹ãªãµãŒããŒçµ±åãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåŠã³ãŸãããã
React useFormStateæ€èšŒãšã³ãžã³ïŒãã«ãã¹ããŒãžãã©ãŒã æ€èšŒã®è©³çް
çŸä»£ã®ãŠã§ãéçºã®äžçã§ã¯ãçŽæçã§å ç¢ãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®æ§ç¯ãæãéèŠã§ããããã¯ããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã®äž»èŠãªã²ãŒããŠã§ã€ã§ãããã©ãŒã 以äžã«éèŠã§ã¯ãããŸãããã·ã³ãã«ãªé£çµ¡å ãã©ãŒã ã¯ç°¡åã§ããããŠãŒã¶ãŒç»é²ãŠã£ã¶ãŒããeã³ããŒã¹ãã§ãã¯ã¢ãŠãã詳现ãªèšå®ããã«ãªã©ããã«ãã¹ããŒãžãã©ãŒã ã§ã¯è€éããæ¥äžæããŸãããããã®ãã«ãã¹ãããããã»ã¹ã¯ãç¶æ 管çãæ€èšŒãã·ãŒã ã¬ã¹ãªãŠãŒã¶ãŒãããŒã®ç¶æã«ãããŠå€§ããªèª²é¡ããããããŸããæŽå²çã«ãéçºè ã¯ããã®è€éããå¶åŸ¡ããããã«ãè€éãªã¯ã©ã€ã¢ã³ãåŽã®ç¶æ ãã³ã³ããã¹ããããã€ããŒãããã³ãµãŒãããŒãã£ã©ã€ãã©ãªãé§äœ¿ããŠããŸããã
Reactã®`useFormState`ããã¯ãç»å ŽããŸããããµãŒããŒçµ±åã³ã³ããŒãã³ãã«åããReactã®é²åã®äžç°ãšããŠå°å ¥ããããã®åŒ·åãªããã¯ã¯ãç¹ã«ãã«ãã¹ããŒãžãã©ãŒã ã®ã³ã³ããã¹ãã§ããã©ãŒã ã®ç¶æ ãšæ€èšŒã管çããããã®ãæŽç·Žããããšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³ãæäŸããŸããServer ActionsãšçŽæ¥çµ±åããããšã«ããã`useFormState`ã¯ãã³ãŒããç°¡çŽ åããããã©ãŒãã³ã¹ãåäžãããããã°ã¬ãã·ããšã³ãã³ã¹ã¡ã³ããæšé²ããå ç¢ãªæ€èšŒãšã³ãžã³ãäœæããŸãããã®èšäºã§ã¯ã`useFormState`ã䜿çšããŠæŽç·Žããããã«ãã¹ããŒãžæ€èšŒãšã³ãžã³ãæ§ç¯ããæ¹æ³ã«ã€ããŠãäžçäžã®éçºè åãã«å æ¬çãªã¬ã€ããæäŸããè€éãªã¿ã¹ã¯ã管çå¯èœã§ã¹ã±ãŒã©ãã«ãªããã»ã¹ã«å€é©ããŸãã
ãã«ãã¹ããŒãžãã©ãŒã ã®æ°žç¶çãªèª²é¡
ãœãªã¥ãŒã·ã§ã³ã詳ãã説æããåã«ãéçºè ããã«ãã¹ããŒãžãã©ãŒã ã§çŽé¢ããäžè¬çãªåé¡ç¹ãçè§£ããããšãéèŠã§ãããããã®èª²é¡ã¯äºçްãªãã®ã§ã¯ãªããéçºæéãããšã³ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®ãã¹ãŠã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
- ç¶æ 管çã®è€éãïŒãŠãŒã¶ãŒãã¹ãããéãç§»åãããšãã«ãããŒã¿ãã©ã®ããã«æ°žç¶åããŸããïŒç¶æ ã¯ã芪ã³ã³ããŒãã³ããã°ããŒãã«ã³ã³ããã¹ãããŸãã¯ããŒã«ã«ã¹ãã¬ãŒãžã«ååšããå¿ èŠããããŸããïŒåã¢ãããŒãã«ã¯ãã¬ãŒããªãããããå€ãã®å Žåãããããããªãªã³ã°ãè€éãªç¶æ åæããžãã¯ã«ã€ãªãããŸãã
- æ€èšŒããžãã¯ã®æçåïŒæ€èšŒã¯ã©ãã§è¡ãå¿ èŠããããŸããïŒãã¹ãŠãæåŸã«æ€èšŒãããšããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæªããªããŸããåã¹ãããã§æ€èšŒããæ¹ãåªããŠããŸãããããã«ã¯ãã¯ã©ã€ã¢ã³ãïŒå³æãã£ãŒãããã¯çšïŒãšãµãŒããŒïŒã»ãã¥ãªãã£ãšããŒã¿ã®æŽåæ§çšïŒã®äž¡æ¹ã§ãæçåãããæ€èšŒããžãã¯ãèšè¿°ããå¿ èŠãããããšããããããŸãã
- ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®ããŒãã«ïŒãŠãŒã¶ãŒã¯ãããŒã¿ã倱ãããšãªãã¹ãããéãç§»åã§ããããšãæåŸ ããŠããŸãããŸããæç¢ºã§ã³ã³ããã¹ãã«å¿ãããšã©ãŒã¡ãã»ãŒãžãšå³æãã£ãŒãããã¯ãæåŸ ããŠããŸãããã®ã¹ã ãŒãºãªãšã¯ã¹ããªãšã³ã¹ãå®è£ ããã«ã¯ãããªãã®ãã€ã©ãŒãã¬ãŒãã³ãŒããå¿ èŠã«ãªãå ŽåããããŸãã
- ãµãŒããŒã¯ã©ã€ã¢ã³ãç¶æ åæïŒçå®ã®æçµçãªãœãŒã¹ã¯éåžžãµãŒããŒã§ããã¯ã©ã€ã¢ã³ãåŽã®ç¶æ ãããµãŒããŒåŽã®æ€èšŒã«ãŒã«ãšããžãã¹ããžãã¯ãšå®å šã«åæãããããšã¯ãåžžã«æŠãã§ãå€ãã®å Žåãã³ãŒãã®éè€ãšæœåšçãªäžæŽåã«ã€ãªãããŸãã
ãããã®èª²é¡ã¯ãããçµ±åãããããŸãšãŸãã®ããã¢ãããŒããã€ãŸãã¯ã©ã€ã¢ã³ããšãµãŒããŒã®ã®ã£ãããåããã¢ãããŒãã®å¿ èŠæ§ã匷調ããŠããŸããããã¯ã`useFormState`ãèŒãå Žæã§ãã
`useFormState`ã®ç»å ŽïŒãã©ãŒã åŠçãžã®ææ°ã®ã¢ãããŒã
`useFormState`ããã¯ã¯ããã©ãŒã ã¢ã¯ã·ã§ã³ã®çµæã«åºã¥ããŠæŽæ°ããããã©ãŒã ã®ç¶æ ã管çããããã«èšèšãããŠããŸããããã¯ãã¯ã©ã€ã¢ã³ãã§JavaScriptãæå¹ã«ãªã£ãŠããå Žåã§ããæå¹ã«ãªã£ãŠããªãå Žåã§ããã·ãŒã ã¬ã¹ã«æ©èœãããããã°ã¬ãã·ãã«åŒ·åãããã¢ããªã±ãŒã·ã§ã³ã«å¯ŸããReactã®ããžã§ã³ã®åºç€ã§ãã
`useFormState`ãšã¯äœã§ããïŒ
åºæ¬çã«ã`useFormState`ã¯ããµãŒããŒã¢ã¯ã·ã§ã³é¢æ°ãšåæç¶æ ã®2ã€ã®åŒæ°ãåãåãReact Hookã§ãããã©ãŒã ã®çŸåšã®ç¶æ ãšã`
);
}
ã¹ããã1ïŒå人æ å ±ã®ååŸãšæ€èšŒ
ãã®ã¹ãããã§ã¯ã`name`ãã£ãŒã«ããš`email`ãã£ãŒã«ãã®ã¿ãæ€èšŒããŸããé ãå ¥å`_step`ã䜿çšããŠãã©ã®æ€èšŒããžãã¯ãå®è¡ãããããµãŒããŒã¢ã¯ã·ã§ã³ã«æç€ºããŸãã
// Step1.jsx component
{state.errors.name} {state.errors.email}
export function Step1({ state }) {
return (
ã¹ããã1ïŒå人æ
å ±
{state.errors?.name &&
{state.errors?.email &&
);
}
次ã«ããµãŒããŒã¢ã¯ã·ã§ã³ãæŽæ°ããŠãã¹ããã1ã®æ€èšŒãåŠçããŸãã
// actions.js (updated)
// ... (imports and schema definition)
export async function onbordingAction(prevState, formData) {
// ... (get form data)
const step = Number(formData.get('_step'));
if (step === 1) {
const validatedFields = schema.pick({ name: true, email: true }).safeParse({ name, email });
if (!validatedFields.success) {
return {
...currentState,
step: 1,
errors: validatedFields.error.flatten().fieldErrors,
};
}
// Success, move to next step
return {
...currentState,
step: 2,
errors: {},
};
}
// ... (logic for other steps)
}
ãŠãŒã¶ãŒããæ¬¡ãžããã¯ãªãã¯ãããšããã©ãŒã ãéä¿¡ãããŸãããµãŒããŒã¢ã¯ã·ã§ã³ã¯ããããã¹ããã1ã§ããããšã確èªããZodã®`pick`ã¡ãœããã䜿çšããŠã®ã¿`name`ãã£ãŒã«ããš`email`ãã£ãŒã«ããæ€èšŒããæ°ããç¶æ ãè¿ããŸããæ€èšŒã«å€±æããå Žåããšã©ãŒãè¿ããã¹ããã1ã«ãšã©ãŸããŸããæåããå Žåããšã©ãŒãã¯ãªã¢ãã`step`ã2ã«æŽæ°ããã¡ã€ã³ã®`OnboardingForm`ã³ã³ããŒãã³ãã`Step2`ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããã«ããŸãã
ã¹ããã2ïŒäŒç€Ÿè©³çŽ°ã®æ®µéçæ€èšŒ
ãã®ã¢ãããŒãã®å©ç¹ã¯ãã¹ããã1ã®ç¶æ ãèªåçã«åŒãç¶ãããããšã§ããæ¬¡ã®ãã©ãŒã éä¿¡ã«å«ããããã«ãé ããã£ãŒã«ãã§ã¬ã³ããªã³ã°ããã ãã§ãã
// Step2.jsx component
{state.errors.companyName} {state.errors.role}
export function Step2({ state }) {
return (
ã¹ããã2ïŒäŒç€Ÿè©³çް
{/* Persist data from previous step */}
{state.errors?.companyName &&
{state.errors?.role &&
);
}
ãããŠããµãŒããŒã¢ã¯ã·ã§ã³ãæŽæ°ããŠãã¹ããã2ãåŠçããŸãã
// actions.js (updated)
// ...
if (step === 2) {
const validatedFields = schema.pick({ companyName: true, role: true }).safeParse({ companyName, role });
if (!validatedFields.success) {
return {
...currentState,
step: 2,
errors: validatedFields.error.flatten().fieldErrors,
};
}
// Success, move to final review
return {
...currentState,
step: 3,
errors: {},
};
}
// ...
ããžãã¯ã¯ã¹ããã1ãšåãã§ãããã¹ããã2ã®ãã£ãŒã«ãã察象ãšããŠããŸãã`useFormState`ããã¯ã¯ããã¹ãŠã®ããŒã¿ãä¿æããã¯ãªãŒã³ã§æ®µéçãªæ€èšŒãããŒãæäŸããããšã«ãããã·ãŒã ã¬ã¹ã«ç§»è¡ã管çããŸãã
ã¹ããã3ïŒæçµç¢ºèªãšéä¿¡
æçµã¹ãããã§ã¯ããŠãŒã¶ãŒã確èªã§ããããã«ãåéããããã¹ãŠã®ããŒã¿ã衚瀺ããŸããæçµçãªéä¿¡ã¯ãããŒã¿ãããŒã¿ããŒã¹ã«ã³ãããããåã«ããã¹ãŠã®ãã£ãŒã«ãã®å æ¬çãªæ€èšŒãããªã¬ãŒããŸãã
// Step3.jsx component
{state.message} {state.message}
export function Step3({ state }) {
return (
ã¹ããã3ïŒè©³çްã®ç¢ºèª
{state.message && state.message.startsWith('Success') &&
{state.message && state.message.startsWith('Error') &&
);
}
æçµçãªãµãŒããŒã¢ã¯ã·ã§ã³ããžãã¯ã¯ãå®å šãªæ€èšŒãšæçµçãªããžãã¹ããžãã¯ãå®è¡ããŸãã
// actions.js (final version)
// ...
if (step === 3) {
// Final, full validation
const validatedFields = schema.safeParse({ name, email, companyName, role });
if (!validatedFields.success) {
// Should not happen if step-by-step validation is correct, but a good safeguard
return {
...currentState,
step: 1, // Send user back to the first step with errors
errors: validatedFields.error.flatten().fieldErrors,
message: 'ãšã©ãŒïŒç¡å¹ãªããŒã¿ãèŠã€ãããŸããã確èªããŠãã ããã'
};
}
try {
// console.log('Submitting to database:', validatedFields.data);
// await saveToDatabase(validatedFields.data);
return { message: 'æåïŒãªã³ããŒãã£ã³ã°ãå®äºããŸããã', step: 4 }; // A final success step
} catch (dbError) {
return { ...currentState, step: 3, message: 'ãšã©ãŒïŒããŒã¿ãä¿åã§ããŸããã§ããã' };
}
}
// ...
ããã«ããã`useFormState`ããã¯ã«ãã£ãŠãã¹ãŠãã¯ãªãŒã³ã«èª¿æŽããããå®å šã§å ç¢ãªã段éçãªãã©ãŒã ãšæ®µéçãªãµãŒããŒèªèšŒæ€èšŒãå®çŸããŸããã
äžçã¯ã©ã¹ã®ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®ããã®é«åºŠãªæŠç¥
æ©èœçãªãã©ãŒã ãæ§ç¯ããããšã¯1ã€ã§ããã䜿ããããããããšã¯å¥ã®ããšã§ãããã«ãã¹ããŒãžãã©ãŒã ãåäžãããããã®é«åºŠãªãã¯ããã¯ã次ã«ç€ºããŸãã
ããã²ãŒã·ã§ã³ã®ç®¡çïŒååŸã«ç§»åãã
çŸåšã®ããžãã¯ã¯åæ¹ã®ã¿ã«ç§»åããŸãããŠãŒã¶ãŒãæ»ããããã«ããã«ã¯ãåçŽãª`type="submit"`ãã¿ã³ã䜿çšããããšã¯ã§ããŸããã代ããã«ãã¯ã©ã€ã¢ã³ãåŽã³ã³ããŒãã³ãã®ç¶æ ã«ã¹ãããã管çãããã©ãŒã ã¢ã¯ã·ã§ã³ã¯åæ¹ãžã®é²è¡ã«ã®ã¿äœ¿çšããŸãããã ãããµãŒããŒäžå¿ã®ã¢ãã«ãç¶æããããç°¡åãªã¢ãããŒãã¯ããæ»ãããã¿ã³ã䜿çšããŠãã©ãŒã ãéä¿¡ããããšã§ãããç°ãªãç®çã§äœ¿çšããããšã§ãã
// ã¹ãããã³ã³ããŒãã³ãå
...
// ãµãŒããŒã¢ã¯ã·ã§ã³å
...
const intent = formData.get('intent');
if (intent === 'back') {
return { ...currentState, step: step - 1, errors: {} };
}
`useFormStatus`ã䜿çšãã峿ãã£ãŒãããã¯ã®æäŸ
`useFormStatus`ããã¯ã¯ãåã`
// SubmitButton.jsx
'use client';
import { useFormStatus } from 'react-dom';
export function SubmitButton({ text }) {
const { pending } = useFormStatus();
return (
{pending ? 'éä¿¡äž...' : text}
);
}
次ã«ãã¹ãããã³ã³ããŒãã³ãã§æšæºã®`
ã¹ã±ãŒã©ããªãã£ã®ããã®ãµãŒããŒã¢ã¯ã·ã§ã³ã®æ§é å
ãã©ãŒã ã倧ãããªãã«ã€ããŠããµãŒããŒã¢ã¯ã·ã§ã³ã®`if/else if`ãã§ãŒã³ã¯æ±ãã«ãããªãå¯èœæ§ããããŸããããè¯ãç·šæã®ããã«ã`switch`ã¹ããŒãã¡ã³ããŸãã¯ããã¢ãžã¥ãŒã«åããããã¿ãŒã³ããå§ãããŸãã
// switchã¹ããŒãã¡ã³ãã䜿çšããactions.js
switch (step) {
case 1:
// Handle Step 1 validation
break;
case 2:
// Handle Step 2 validation
break;
// ... etc
}
ã¢ã¯ã»ã·ããªãã£ïŒa11yïŒã¯å¿ é ã§ã
ã°ããŒãã«ãªèŠèŽè ã«ãšã£ãŠãã¢ã¯ã»ã·ããªãã£ã¯å¿ é ã§ãããã©ãŒã ã«ã¢ã¯ã»ã¹ã§ããããã«ã以äžã確èªããŠãã ããã
- ãšã©ãŒã®ããå ¥åãã£ãŒã«ãã«`aria-invalid="true"`ã䜿çšããŸãã
- `aria-describedby`ã䜿çšããŠããšã©ãŒã¡ãã»ãŒãžãã€ã³ãããã«æ¥ç¶ããŸãã
- éä¿¡åŸãç¹ã«ãšã©ãŒã衚瀺ãããå Žåã¯ãé©åã«ãã©ãŒã«ã¹ã管çããŸãã
- ãã¹ãŠã®ãã©ãŒã ã³ã³ãããŒã«ãããŒããŒãã§ããã²ãŒãå¯èœã§ããããšã確èªããŸãã
ã°ããŒãã«ãªèŠç¹ïŒåœéåãš`useFormState`
ãµãŒããŒé§ååæ€èšŒã®å€§ããªå©ç¹ã®1ã€ã¯ãåœéåïŒi18nïŒã®å®¹æãã§ããæ€èšŒã¡ãã»ãŒãžãã¯ã©ã€ã¢ã³ãã§ããŒãã³ãŒãã£ã³ã°ããå¿ èŠã¯ãªããªããŸããããµãŒããŒã¢ã¯ã·ã§ã³ã¯ããŠãŒã¶ãŒã®åªå èšèªïŒ`Accept-Language`ã®ãããªããããŒãããURLãã©ã¡ãŒã¿ããããŸãã¯ãŠãŒã¶ãŒãããã¡ã€ã«èšå®ããïŒãæ€åºããæ¯åœèªã§ãšã©ãŒãè¿ãããšãã§ããŸãã
ããšãã°ããµãŒããŒã§`i18next`ã®ãããªã©ã€ãã©ãªã䜿çšããïŒ
// i18nã䜿çšãããµãŒããŒã¢ã¯ã·ã§ã³
import { i18n } from 'your-i18n-config';
// ...
const t = await i18n.getFixedT(userLocale); // e.g., 'es' for Spanish
const schema = z.object({
email: z.string().email(t('errors.invalid_email')),
});
ãã®ã¢ãããŒãã«ãããäžçäžã®ãŠãŒã¶ãŒãæç¢ºã§ãããããããã£ãŒãããã¯ãåãåããã¢ããªã±ãŒã·ã§ã³ã®å æ¬æ§ãšäœ¿ãããããå€§å¹ ã«åäžããŸãã
`useFormState`ãšã¯ã©ã€ã¢ã³ããµã€ãã©ã€ãã©ãªïŒæ¯èŒ
ãã®ãã¿ãŒã³ã¯ãFormikãReact Hook Formã®ãããªç¢ºç«ãããã©ã€ãã©ãªãšæ¯èŒããŠã©ãã§ããïŒã©ã¡ããåªããŠãããã§ã¯ãªããã©ãããã®ä»äºã«é©ããŠããããšããããšã§ãã
- ã¯ã©ã€ã¢ã³ããµã€ãã©ã€ãã©ãªïŒFormikãReact Hook FormïŒïŒãããã¯ã峿ã¯ã©ã€ã¢ã³ããµã€ããã£ãŒãããã¯ãæåªå äºé ã§ãããè€éã§é«åºŠãªã€ã³ã¿ã©ã¯ãã£ããã©ãŒã ã«æé©ã§ãããã©ãŒã ã®ç¶æ ãæ€èšŒãããã³éä¿¡ãå®å šã«ãã©ãŠã¶å ã§ç®¡çããããã®å æ¬çãªããŒã«ããããæäŸããŸããäž»ãªèª²é¡ã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®æ€èšŒããžãã¯ã®éè€ã§ãã
- Server Actionsã䜿çšãã`useFormState`ïŒãã®ã¢ãããŒãã¯ããµãŒããŒãçå®ã®æçµçãªãœãŒã¹ã§ããå Žåã«åªããŠããŸããããžãã¯ãäžå åããããšã§ãå šäœçãªã¢ãŒããã¯ãã£ãç°¡çŽ åããããŒã¿ã®æŽåæ§ãä¿èšŒããããã°ã¬ãã·ããšã³ãã³ã¹ã¡ã³ããšã·ãŒã ã¬ã¹ã«é£æºããŸãããã¬ãŒããªãã¯ãæ€èšŒã®ããã®ãããã¯ãŒã¯ã®ã©ãŠã³ãããªããã§ãããææ°ã®ã€ã³ãã©ã¹ãã©ã¯ãã£ã§ã¯ãããã¯ç¡èŠã§ããããšããããããŸãã
éèŠãªããžãã¹ããžãã¯ããããŒã¿ããŒã¹ã«å¯ŸããŠæ€èšŒããå¿ èŠãããããŒã¿ïŒããšãã°ããŠãŒã¶ãŒåã䜿çšãããŠãããã©ããã確èªããïŒãå«ããã«ãã¹ããŒãžãã©ãŒã ã®å Žåã`useFormState`ãã¿ãŒã³ã¯ãããçŽæ¥çã§ãšã©ãŒãçºçãã«ããã¢ãŒããã¯ãã£ãæäŸããŸãã
çµè«ïŒReactã«ããããã©ãŒã ã®æªæ¥
`useFormState`ããã¯ã¯åãªãæ°ããAPI以äžã®ãã®ã§ããããã¯ãReactã§ãã©ãŒã ãæ§ç¯ããæ¹æ³ã«ãããå²åŠçãªå€åã衚ããŠããŸãããµãŒããŒäžå¿ã®ã¢ãã«ãæ¡çšããããšã«ãããããå ç¢ã§ãå®å šã§ãã¢ã¯ã»ã¹å¯èœã§ãä¿å®ã容æãªãã«ãã¹ããŒãžãã©ãŒã ãäœæã§ããŸãããã®ãã¿ãŒã³ã¯ãç¶æ åæã«é¢é£ãããã¹ãŠã®ã«ããŽãªã®ãã°ãæé€ããè€éãªãŠãŒã¶ãŒãããŒãåŠçããããã®ãæç¢ºã§ã¹ã±ãŒã©ãã«ãªæ§é ãæäŸããŸãã
`useFormState`ã䜿çšããŠæ€èšŒãšã³ãžã³ãæ§ç¯ããããšã«ãããç¶æ ã管çããŠããã ãã§ãªããææ°ã®Webéçºã®ååã«åºã¥ãããå埩åã®ãããŠãŒã¶ãŒãã¬ã³ããªãŒãªããŒã¿åéããã»ã¹ãæ§ç¯ããŠããŸãã倿§ãªã°ããŒãã«ãªèŠèŽè åãã®ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããéçºè ã«ãšã£ãŠããã®åŒ·åãªããã¯ã¯ãçã«äžçã¯ã©ã¹ã®ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãäœæããããã®åºç€ãæäŸããŸãã