我遇到了一个问题,每当我设置const buyFormData时,数组确实得到更新,但其余代码(更新输入字段)停止工作。没有JavaScript错误。代码就挂在那里。在我的子组件上,我能够console.log并显示新数组。然而,由于代码停止更新,它只在我第一次点击“加”或“减”按钮时才起作用。
注解:“setBuyFormData(updatedValues);“允许输入自由更新,但从不更新子组件的值。
我怎么调试这个?JavaScript控制台中没有错误。
我用的是NextJs 13。
编辑:用Prettier格式化代码。我有点绝望了,我已经想了将近一个星期了。任何帮助都欢迎。
'use client';
import React from 'react';
import { MinusIcon, PlusIcon } from '@heroicons/react/20/solid';
import { useEffect, useState } from 'react';
import { FieldValues, useForm, useFormContext } from 'react-hook-form';
import TicketSummaryCard from './TicketSummaryCard';
//Typing
type EleventlyEvent = {
event: Event;
event_title: string;
};
function TicketSelection({ event }: EleventlyEvent) {
const readFormData = useFormContext();
const [buyformData, setBuyFormData] = useState([{}]);
useEffect(() => {}, [buyformData]);
const [formFields, setFormFields] = useState([
{
id: '0',
ticketName: 'Régulier',
description: 'Régulier',
price: '40.00',
limit: '5'
},
{
id: '1',
ticketName: 'Admission',
description: 'Ceci est une description Admission',
price: '10.00',
limit: '10'
},
{
id: '2',
ticketName: 'VIP',
description: 'Ceci est une description VIP',
price: '80.00',
limit: '1'
},
{
id: '3',
ticketName: 'ENFANT',
description: 'Voici le billet pour enfant',
price: '25.00',
limit: '2'
}
]);
const handleTicketChange = (e: any, action: string) => {
//Get the ticket Limit number from the input field data* attribute
let buyLimit: number = e.getAttribute('data-limit');
let fieldName: string = e.name;
let fieldCurrentValue: number = parseInt(e.value);
switch (action) {
case 'plus':
if (fieldCurrentValue < buyLimit) {
let updatedValue: number = fieldCurrentValue + 1;
e.value = updatedValue;
setValue(fieldName, updatedValue);
} else {
//Error Message for Limit reached
return;
}
break;
case 'minus':
if (fieldCurrentValue > 0) {
let updatedValue: number = fieldCurrentValue - 1;
e.value = updatedValue;
setValue(fieldName, updatedValue);
} else {
//Error Message for Limit below minimum
return;
}
break;
}
//After doing the maths update the buy list for the summary card
updateBuyList();
};
const updateBuyList = () => {
//Read all form
let tempBuyList: FieldValues = readFormData.getValues();
let updatedValues: {
ticketName: string;
ticketPrice: number;
ticketNumber: number;
}[] = [];
for (var key in tempBuyList) {
//Loop through the FieldValues in the forms
if (tempBuyList.hasOwnProperty(key)) {
formFields?.map((formField, index) => {
if (key === formField.ticketName) {
let newValues = {
ticketName: key,
ticketPrice: formField.price,
ticketNumber: tempBuyList[key]
};
//Only add the ticket to the array if the number is defined
if (tempBuyList[key]) {
updatedValues.push(newValues);
}
}
});
}
}
//This breaks the rest of the form. if i update the value the forms break but the value gets passed only for the firstime.
setBuyFormData(updatedValues);
};
const updateTicketNumber = (target) => {};
const {
register,
setValue,
formState: { errors }
} = useFormContext();
return (
<>
<main className="bg-white">
<div className="mx-auto max-w-8xl px-4 sm:px-2">
<div className="py-12 grid max-w-2xl grid-cols-1 grid-rows-1 items-start gap-x-8 gap-y-8 lg:mx-0 lg:max-w-none lg:grid-cols-12">
<div className="col-span-7 lg:col-span-9 lg:col-start-1 lg:row-end-1">
<h1 className="text-black font-semibold text-3xl">
Selection de billets
</h1>
<div className="">
{formFields.map((item, index) => (
<div
className="rounded-lg bg-white shadow-sm ring-1 ring-gray-900/5 my-10"
key={index}
>
<dl className="flex flex-wrap">
<div className="flex-auto pl-6 pt-6">
<span className="text-base font-semibold leading-6 text-gray-900">
{item.ticketName}
</span>
</div>
<div className="flex-none self-end px-6 pt-4">
<div className="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
<div className="flex flex-row" key={index}>
<button
type="button"
onClick={(e) => {
handleTicketChange(
e.currentTarget.nextSibling,
'minus'
);
}}
className="rounded-sm bg-[#33DEBD] p-1.5 text-black shadow-sm hover:bg-primaryhover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600"
>
<MinusIcon
className="h-3 w-3 rounded"
aria-hidden="true"
/>
</button>
<input
className="mx-auto w-12 p-0 m-0 text-center border-0 text-gray-900 bg-transparent font-semibold"
id={item.id}
data-limit={item.limit}
value={0}
{...register(item.ticketName)}
/>
<button
type="button"
onClick={(e) => {
handleTicketChange(
e.currentTarget.previousSibling,
'plus'
);
}}
className="rounded-sm bg-[#33DEBD] p-1.5 text-black shadow-sm hover:bg-primaryhover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600"
>
<PlusIcon
className="h-3 w-3 rounded"
aria-hidden="true"
/>
</button>
</div>
</div>
</div>
</dl>
<div className="mt-6 border-t border-gray-900/5 px-6 py-6">
<dt className="text-md font-semibold leading-6 text-gray-900">
{item.price}
</dt>
<dl className="leading-6 font-normal text-gray-500">
{item.description}
</dl>
</div>
</div>
))}
</div>
</div>
{/* Ticket Price summary */}
<div className="col-span-7 lg:col-span-7 lg:row-end-1 ">
<TicketSummaryCard event={event} buylist={buyformData} />
</div>
</div>
</div>
</main>
</>
);
}
export default TicketSelection;
1条答案
按热度按时间mm9b1k5b1#
我给你做了一个注解版本,有效地利用了React的状态。其实我没改多少,但最值得注意的是:
我希望它能帮助你继续你的旅程,使这项工作。该代码在Sandbox中可用,因此您可以使用它。
祝你好运!