Как сделать часть схемы Zod необязательной только при отправке?Javascript

Форум по Javascript
Ответить
Anonymous
 Как сделать часть схемы Zod необязательной только при отправке?

Сообщение Anonymous »

У меня есть проект React, использующий TypeScript, React Hook Form и Zod.
Моя схема Zod выглядит следующим образом:

Код: Выделить всё

import { z } from 'zod';

export const loyaltyNmvFormSchema = z.object({
maxPoint: z.coerce.number().min(1, "Max point is required"),
cityForm: z.object({
cityId: z.string().nonempty('City must be selected'),
baseFare: z.coerce.number().min(1, 'Base Fare is required'),
}),
cities: z
.array(
z.object({
cityId: z.string().nonempty("City is required"),
baseFare: z.coerce.number().min(1, "Base fare must be greater than 0"),
})
)
.min(1, "At least one city is required"),
});
И моя форма инициализируется следующим образом:

Код: Выделить всё

  const {
handleSubmit,
control,
resetField,
watch,
setError,
formState: { errors },
} = useForm({
resolver: zodResolver(loyaltyNmvFormSchema.partial({
cityForm: true,
})),
defaultValues: {
maxPoint: 0,
cityForm: { cityId: "", baseFare: 0 },
cities: [],
},
mode: 'onSubmit',
});
Я хочу, чтобы поле cityForm было необязательным только при отправке, потому что я проверяю его вручную внутри handleAddCity.
Однако, хотя я использовал .partial({ cityForm: true }), Zod все равно проверяет cityForm, когда я нажимаю кнопку отправки.
Вот логика handleAddCity:

Код: Выделить всё

  const { fields, append, remove } = useFieldArray({
control,
name: "cities",
});

const handleAddCity = () => {
const cityForm = watch("cityForm");
const parsed = loyaltyNmvFormSchema.pick({ cityForm: true }).shape.cityForm.safeParse(cityForm);

console.log(parsed,'PARSED');

if (!parsed.success) {
parsed.error.errors.forEach((err) => {
const fieldName = `cityForm.${err.path[0]}` as
| "cityForm.cityId"
| "cityForm.baseFare";
setError(fieldName, { message: err.message });
});
return;
}

if (!cityForm.cityId || !cityForm.baseFare) return;
append({ ...cityForm });
resetField("cityForm");
};

И обработчик отправки:

Код: Выделить всё

 const handleSubmitForm = (data: loyaltyNmvFormFields) => {
console.log(data,'DATA');
return;
const {cities} = data;
if (cities.length === 0) {
toast.error('You must add at least one city');
return;
}
console.log(data, 'DATA');
};

Я хочу сделать cityForm необязательным в onSubmit, потому что я проверяю это в handleAddCity,
и я не хочу, чтобы он проверялся на кнопке отправки, я уже использовал частичный, но, похоже, он не работает, и когда я нажимаю кнопку отправки, я снова вижу, что поля города проверяются,
это мой jsx

Код: Выделить всё

    



 (
 field.onChange(Number(val))}
errorMessage={errors.maxPoint?.message}
isInvalid={Boolean(errors.maxPoint)}
/>
)}
/>


 (
 city.cityId)}
isInvalid={!!errors.cityForm?.cityId}
errorMessage={errors.cityForm?.cityId?.message || ''}
>
{adminCities.map((city) => (
{city.name}
))}

)}
/>

  (
 field.onChange(Number(val))}
isInvalid={!!errors.cityForm?.baseFare}
errorMessage={errors.cityForm?.baseFare?.message}
/>
)}
/>

{t("add")}


{fields.length > 0 && (


{(column) => {column.label}}


{fields.map((field, index) => (

{findCityNameById(field.cityId)}

 (
 field.onChange(Number(val))}
isInvalid={Boolean(errors.cities?.[index]?.baseFare)}
errorMessage={errors.cities?.[index]?.baseFare?.message}
/>
)}
/>


 handleRemoveTableRow(index)}
>




))}


)}
{/* Submit Button */}

{t("submit")}




Мне нужно:
cityForm проверялся только внутри handleAddCity,
но игнорировался во время окончательной проверки отправки.
partial({ cityForm: true }) не отключал проверку — Zod по-прежнему проверяет cityForm при отправке.>

Подробнее здесь: https://stackoverflow.com/questions/798 ... -on-submit
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»