如何使用 React Js 组合表单?[附上片段]

IT技术 javascript json reactjs forms next.js
2021-05-05 09:18:29

我正在尝试在 reactjs 中制作一个像https://jsonresume.org/schema/(JSON格式)这样的表单

索引.js:

import React, { useState, Fragment } from 'react';
import BasicDetails from '../components/basic_details';
import EmploymentDetails from '../components/employment_details';

const App = () => {
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('get the whole form json here');
  };

  return (
    <>
      <h1>Dynamic Form Fields in React</h1>
      <form onSubmit={handleSubmit}>
        Basic Details:
        <br />
        <hr />
        <BasicDetails />
        <br />
        <br />
        Employment Details:
        <br />
        <hr />
        <EmploymentDetails />
        <div className="submit-button">
          <button
            className="btn btn-primary mr-2"
            type="submit"
            onSubmit={handleSubmit}
          >
            Save
          </button>
        </div>
        {/* <pre>{JSON.stringify(inputFields, null, 2)}</pre> */}
      </form>
    </>
  );
};

export default App;

可以在附加的代码<BasicDetails />框中找到诸如<EmploymentDetails />代码之类的组件。

在这里,我使表单为每个喜欢的人都有一个单独的组件,

---> Basic Details
---> Employment Details
---> ...So on ...

要求:

我在需要这些投入在一个JSON格式结合这样的

现在我有不同文件中的基本详细信息和就业详细信息 那么如何将这两个文件/组件组合成一个完整的 JSON?

单击提交按钮 (index.js) 时预期的 JSON 格式:

{
  "basicDetails": {
    "firstName": "John",
    "lastName": "Doe"
  },
  "companyDetails": [{
     "companyName": "xyz",
     "designation": "lmn"
   },
   {
     "companyName": "abc",
     "designation": "def"
   }
 ]
}

查看以下代码和框,其中包含相应组件中输入字段的 JSON 格式。我需要组合这些并在单击提交按钮时显示最终表单。

Codesandbox: https ://codesandbox.io/s/next-dynamic-testing-issue-forked-ieqf5

注意:组件部分将不断增加,我们将添加新组件,如技能、教育细节(此处未添加,但将来会添加)等,因此请相应地提供解决方案。

非常感谢提前..

2个回答

这可以使用ContextAPI来完成这个想法是让您的状态在多个组件之间共享。

下面的代码将举行formValue,将上访问EmploymentDetailsBasicDetails组件。

// components/form_context.js

import React, { useState } from 'react';

export const FormContext = React.createContext();

export function FormProvider({ children }) {
  const [formValue, setFormValue] = useState({
    basicDetails: {
      firstName: '',
      lastName: '',
    },
    companyDetails: [
      {
        companyName: '',
        designation: '',
      },
    ],
  });

  return (
    <FormContext.Provider value={[formValue, setFormValue]}>
      {children}
    </FormContext.Provider>
  );
}

在您的 上BasicDetails,您可以formValue通过以下方式访问上述状态

// components/basic_details.js

import { FormContext } from './form_context';

const BasicDetails = () => {
  const [value, setValue] = React.useContext(FormContext); // here
  const { basicDetails } = value;

  const handleInputChange = (event) => {
    const { name, value } = event.target;
    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

  ...
};

-也通知我们如何实现我们的handleInputChange,我们要更新formValue使用setValue我们的到来FormContext

检查演示,并询问我是否要澄清任何内容。在这里阅读Context文档

编辑下一个动态测试问题(分叉)

这是一个可能的解决方案我只编码了 basicDetails 但其余字段的原理是相同的:

  1. 您必须使用fieldChangeprops处理从子组件到父组件的更改
    const BasicDetails = ({ fieldChange }) => {
    
    ...
    
      const handleInputChange = (event) => {

        if (event.target.name === 'firstName') {
          setInputField({ ...inputField, firstName: event.target.value });
        } else {
          setInputField({ ...inputField, lastName: event.target.value });
        }
        fieldChange(inputField);
      };
  1. 保持父组件状态的变化:
    <BasicDetails fieldChange={(value) => setBasicDetails(value)} />

另一种解决方案是useForm,具体取决于您的项目复杂性