React useState hook 并以多步形式提交
React useState hook and submit in multi step form
我正在使用 React JsonSchema Form 创建一个多步骤表单。每次单击页面上的下一步按钮并最后提交时,我都想更新我的状态。 React JsonSchema Form 仅在按钮类型为提交时才验证条目。所以我的下一步按钮是提交按钮。
由于表单会有多个问题,我的状态是对象数组。由于 useState 的异步特性,我更新后的状态值无法立即保存到后端。我应该如何获得最终值?
当我调试时,我可以看到上一步之前的数据。有没有办法让 useState 表现得像同步调用?
完整代码如下:
const data = [
{
page: {
id: 1,
title: "First Page",
schema: {
title: "Todo 1",
type: "object",
required: ["title1"],
properties: {
title1: { type: "string", title: "Title", default: "A new task" },
done1: { type: "boolean", title: "Done?", default: false },
},
},
},
},
{
page: {
id: 1,
title: "Second Page",
schema: {
title: "Todo 2",
type: "object",
required: ["title2"],
properties: {
title2: { type: "string", title: "Title", default: "A new task" },
done2: { type: "boolean", title: "Done?", default: false },
},
},
},
},
];
interface IData {
id: Number;
data: any
};
export const Questions: React.FunctionComponent = (props: any) => {
const [currentPage, setCurrentPage] = useState(0);
const [surveyData, setSurveyData] = useState<IData[]>([]);
const handleNext = (e: any) => {
setSurveyData( previous => [
...previous,
{
id: currentPage,
data: e.formData,
},
]);
if (currentPage < data.length) setCurrentPage(currentPage + 1);
else //Here I want to submit the data
};
const handlePrev = () => {
setCurrentPage(currentPage - 1);
};
return (
<Form
schema={data[currentPage].page.schema as JSONSchema7}
onSubmit={handleNext}
>
<Button variant="contained" onClick={handlePrev}>
Prev
</Button>
<Button type="submit" variant="contained">
Next
</Button>
</Form>
);
};
您可以合并 useEffect
挂钩,它将触发您想要的状态更改。
像这样:
useEffect(() => {
// reversed conditional logic
if (currentPage > data.length) {
submit(surveyData);
}
}, [currentPage])
const handleNext = (e: any) => {
setSurveyData( previous => [
...previous,
{
id: currentPage,
data: e.formData,
},
]);
if (currentPage < data.length) setCurrentPage(currentPage + 1);
// remove else
};
我会重构新的状态结构以使用状态的实际值而不是回调值,因为这将允许您在设置后访问整个结构:
const handleNext = (e: any) => {
const newSurveyData = [
...surveyData,
{
id: currentPage,
data: e.formData
}
];
setSurveryData(newSurveyData);
if (currentPage < data.length) {
setCurrentPage(currentPage + 1);
} else {
// submit newSurveryData
};
};
旁注:您还必须考虑这样一个事实,即返回页面意味着您必须按索引拼接新的调查数据,而不是每次都将其附加到末尾。
在您上次提交时,您将在 surveyData
中获得所有以前的数据,但您将在 e.formData
中获得最新答案。您需要做的是将它们组合起来并发送到服务器。
// in your onSubmit handler
else {
myApiClient.send({ answers: [...surveyData, e.formData] })
}
我正在使用 React JsonSchema Form 创建一个多步骤表单。每次单击页面上的下一步按钮并最后提交时,我都想更新我的状态。 React JsonSchema Form 仅在按钮类型为提交时才验证条目。所以我的下一步按钮是提交按钮。
由于表单会有多个问题,我的状态是对象数组。由于 useState 的异步特性,我更新后的状态值无法立即保存到后端。我应该如何获得最终值?
当我调试时,我可以看到上一步之前的数据。有没有办法让 useState 表现得像同步调用?
完整代码如下:
const data = [
{
page: {
id: 1,
title: "First Page",
schema: {
title: "Todo 1",
type: "object",
required: ["title1"],
properties: {
title1: { type: "string", title: "Title", default: "A new task" },
done1: { type: "boolean", title: "Done?", default: false },
},
},
},
},
{
page: {
id: 1,
title: "Second Page",
schema: {
title: "Todo 2",
type: "object",
required: ["title2"],
properties: {
title2: { type: "string", title: "Title", default: "A new task" },
done2: { type: "boolean", title: "Done?", default: false },
},
},
},
},
];
interface IData {
id: Number;
data: any
};
export const Questions: React.FunctionComponent = (props: any) => {
const [currentPage, setCurrentPage] = useState(0);
const [surveyData, setSurveyData] = useState<IData[]>([]);
const handleNext = (e: any) => {
setSurveyData( previous => [
...previous,
{
id: currentPage,
data: e.formData,
},
]);
if (currentPage < data.length) setCurrentPage(currentPage + 1);
else //Here I want to submit the data
};
const handlePrev = () => {
setCurrentPage(currentPage - 1);
};
return (
<Form
schema={data[currentPage].page.schema as JSONSchema7}
onSubmit={handleNext}
>
<Button variant="contained" onClick={handlePrev}>
Prev
</Button>
<Button type="submit" variant="contained">
Next
</Button>
</Form>
);
};
您可以合并 useEffect
挂钩,它将触发您想要的状态更改。
像这样:
useEffect(() => {
// reversed conditional logic
if (currentPage > data.length) {
submit(surveyData);
}
}, [currentPage])
const handleNext = (e: any) => {
setSurveyData( previous => [
...previous,
{
id: currentPage,
data: e.formData,
},
]);
if (currentPage < data.length) setCurrentPage(currentPage + 1);
// remove else
};
我会重构新的状态结构以使用状态的实际值而不是回调值,因为这将允许您在设置后访问整个结构:
const handleNext = (e: any) => {
const newSurveyData = [
...surveyData,
{
id: currentPage,
data: e.formData
}
];
setSurveryData(newSurveyData);
if (currentPage < data.length) {
setCurrentPage(currentPage + 1);
} else {
// submit newSurveryData
};
};
旁注:您还必须考虑这样一个事实,即返回页面意味着您必须按索引拼接新的调查数据,而不是每次都将其附加到末尾。
在您上次提交时,您将在 surveyData
中获得所有以前的数据,但您将在 e.formData
中获得最新答案。您需要做的是将它们组合起来并发送到服务器。
// in your onSubmit handler
else {
myApiClient.send({ answers: [...surveyData, e.formData] })
}