0

我正在使用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>
 );
};
4

3 回答 3

1

您可以合并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
};
于 2020-11-28T00:14:42.907 回答
1

在您上次提交时,您将在 中获得所有以前的数据surveyData,但您将在 中获得最新答案e.formData。您需要做的是组合这些并将其发送到服务器。

// in your onSubmit handler
else {
  myApiClient.send({ answers: [...surveyData, e.formData] })
}
于 2020-11-28T00:28:17.003 回答
0

我将重构新的状态结构以使用状态的实际值而不是回调值,因为这将允许您在设置后访问整个结构:

  const handleNext = (e: any) => {
    const newSurveyData = [
        ...surveyData,
        {
            id: currentPage,
            data: e.formData
        }
    ];

    setSurveryData(newSurveyData);

    if (currentPage < data.length) {
        setCurrentPage(currentPage + 1);
    } else {
        // submit newSurveryData
    };
  };

附注:您还必须考虑这样一个事实,即返回页面意味着您必须按索引拼接新的调查数据,而不是每次都将其附加到末尾。

于 2020-11-28T00:24:49.113 回答