Reactjs 使用react/typescript中的final表单从嵌套表单获取值

Reactjs 使用react/typescript中的final表单从嵌套表单获取值,reactjs,typescript,react-final-form,Reactjs,Typescript,React Final Form,我无法使用final form从嵌套表单中获取值 这是我的索引。tsx import React, { useState, ChangeEvent } from 'react'; import { Form } from 'react-final-form'; import { Box, Typography, Button, IconButton, Grid, FormControl, InputLabel, Select, } from '@material-ui/core'; impo

我无法使用final form从嵌套表单中获取值

这是我的索引。tsx

import React, { useState, ChangeEvent } from 'react';
import { Form } from 'react-final-form';
import {
  Box, Typography, Button, IconButton, Grid, FormControl, InputLabel, Select,
} from '@material-ui/core';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import FieldInput from 'forms/shared/fields/input';
import FieldFileUploader from 'forms/shared/fields/file-uploader';
import FieldCheckbox from 'forms/shared/fields/checkbox';
import FormRadioQuestions from './partials/form-radio';
import FormExperience from './partials/form-experience';
import FormEducation from './partials/form-education';
import FormPersonalInfo from './partials/form-personal-info';
import FormGovernmentIds from './partials/form-government-id';
import ItemExperience from './partials/experience-item';
import ItemEducation from './partials/education-item';
import useStyles from './styles';

const PublicApplicationForm = () => {
  const [state, setState] = useState<{ client: string | number; name: string }>({ client: '', name: 'hai' });
  const [showExp, setOpenExp] = useState(false);
  const [showEdu, setOpenEdu] = useState(false);
  const [data, setData] = useState({
    experience: [{}],
  });
  const [educations, setEducations] = useState([]);
  const [experiences, setExperiences] = useState([]);
  const classes = useStyles();
  const radioValues = [{ value: 'yes', label: 'Yes' }, { value: 'no', label: 'No' }];
  const variables = { title: 'How did you hear about us?*', typeOfService: 'Type of Service*' };
  const relationOptions = ['Walk-In', 'Employee Referral', 'Job Boards', 'Job Fair', 'Social Media'];
  const checkBoxLabel = 'Please be informed that your application to this job offer will trigger some processing of your personal data by the  company. For more information on data processing, please refer to the company’s talent acquisition privacy policy.';

  const handleChange = ({ target }: ChangeEvent<{ name?: string; value: unknown }>) => {
    setState({ ...state, [target.name as keyof typeof state]: target.value });
  };

  const handleBlur = (event: any) => {
    data.experience[0] = { ...data.experience[0], [event.target.name]: event.target.value };
    setData({ ...data });
  };

  const onAddEdu = (edu: any) => { setEducations([...educations, edu]); setOpenEdu(false); };
  const onAddExp = (exp: any) => { setExperiences([...experiences, exp]); setOpenExp(false); };

  return (
    <Grid className={classes.pageContainer} container>
      <Grid className={classes.formContainer} item xs={12}>
        <Form
          onSubmit={(values) => { console.log(values); }} // eslint-disable-line no-console
          render={({ handleSubmit }) => (
            <form onSubmit={handleSubmit}>
              <Typography className={classes.formHeading} variant="h5">Personal Information</Typography>
              <Box className={classes.marginedBottom}>
                <FieldFileUploader
                  required
                  fileType="avatars"
                  accept={['image/*']}
                  name="resume"
                />
              </Box>
              <FormPersonalInfo setData={setData} data={data} />
              <Box className={classes.spaced}>
                <Box className={classes.fieldContainer}>
                  <Typography className={classes.noMarginBottom} variant="h6">Experience</Typography>
                  <IconButton color="primary" onClick={() => { setOpenExp(!showExp); }}><AddCircleIcon /></IconButton>
                </Box>
                {
                  showExp && (
                    <FormExperience
                      onCancel={() => setOpenExp(false)}
                      onSave={onAddExp}
                      handleBlur={handleBlur}
                    />
                  )
                }
                {experiences.map((exp, index) => <ItemExperience key={index} exp={exp} />)}
              </Box>
              <Box className={classes.spaced}>
                <Box className={classes.fieldContainer}>
                  <Typography className={classes.noMarginBottom} variant="h6">Education</Typography>
                  <IconButton color="primary" onClick={() => { setOpenEdu(!showEdu); }}><AddCircleIcon /></IconButton>
                </Box>
                {
                  showEdu && (
                    <FormEducation
                      onCancel={() => setOpenEdu(false)}
                      onSave={onAddEdu}
                      setData={setData}
                      data={data}
                    />
                  )
                }
                {educations.map((edu, index) => <ItemEducation key={index} edu={edu} />)}
              </Box>
              <Typography className={classes.formText} variant="h6">On the web</Typography>
              <Box className={classes.fieldContainer}>
                <FieldInput className={classes.textField} type="text" required name="applicant-linkedin" label="Linkedin" onChange={(event: React.ChangeEvent<HTMLInputElement>) => setData({ ...data, [event.target.name]: event.target.value })} />
              </Box>
              <Box className={`${classes.fieldContainer} ${classes.marginedBottom}`}>
                <FieldInput className={classes.textField} type="text" required name="applicant-facebook" label="Facebook" onChange={(event: React.ChangeEvent<HTMLInputElement>) => setData({ ...data, [event.target.name]: event.target.value })} />
              </Box>
              <Typography className={classes.formText} variant="h6">Resume</Typography>
              <Box className={`${classes.fieldContainer} ${classes.marginedBottom}`}>
                <Box className={classes.dropZone}>
                  <FieldFileUploader
                    required
                    fileType="resumes"
                    fieldLabel="Click or Drag file here to upload resume"
                    accept={['application/pdf']}
                    name="resume"
                  />
                </Box>
              </Box>
              <Typography className={classes.formText} variant="h6">Check the box of the ones you don&apos;t have.</Typography>
              <Box className={classes.marginedBottom}>
                <FormGovernmentIds setData={setData} data={data} />
              </Box>
              <Typography className={classes.formText} variant="h6">Preliminary Questions</Typography>
              <Box className={`${classes.fieldContainer} ${classes.marginedBottom}`}>
                <FormControl variant="outlined" className={classes.textField}>
                  <InputLabel htmlFor="outlined-age-native-simple">{variables.title}</InputLabel>
                  <Select
                    native
                    value={state.client}
                    onChange={handleChange}
                    label="How did you hear about us?"
                    inputProps={{ name: 'client', id: 'outlined-age-native-simple' }}
                    onClick={
                      (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => setData({
                        ...data,
                        [event.target.name]: event.target.value,
                      })
                    }
                  >
                    <option aria-label="None" value="" />
                    {relationOptions.map((item, index) => (
                      <option key={index} value={item.replace(' ', '-').toLowerCase()}>{item}</option>))}
                  </Select>
                </FormControl>
              </Box>
              <FormRadioQuestions
                fieldClassName={classes.fieldContainer}
                textClassName={classes.textField}
                values={radioValues}
                setData={setData}
                data={data}
              />
              <Box className={classes.fieldContainer}>
                <FieldCheckbox className={classes.textField} name="confirm-registration" label={checkBoxLabel} />
              </Box>
              <Box className={classes.fieldContainer}>
                <Button component="button" type="submit" className={classes.spaced} variant="contained" color="primary">
                  Submit
                </Button>
              </Box>
            </form>
          )}
        />
      </Grid>
    </Grid>
  );
};

export default PublicApplicationForm;
import React,{useState,ChangeEvent}来自'React';
从“react final Form”导入{Form};
进口{
框、排版、按钮、图标按钮、网格、窗体控件、InputLabel、选择、,
}来自“@material ui/core”;
从“@material ui/icons/AddCircle”导入AddCircleIcon;
从“表单/共享/字段/输入”导入字段输入;
从“forms/shared/fields/file uploader”导入FieldFileUploader;
从“表单/共享/字段/复选框”导入字段复选框;
从“./partials/form radio”导入FormRadio问题;
从“./partials/form experience”导入FormExperience;
从“/partials/form education”导入FormEducation;
从“./partials/form personal info”导入FormPersonalInfo;
从“./partials/form government id”导入FormGovernmentId;
从“./partials/experience item”导入ItemExperience;
从“./partials/education item”导入项目教育;
从“./styles”导入useStyles;
const PublicApplicationForm=()=>{
const[state,setState]=useState({client:'',name:'hai'});
const[showExp,setOpenExp]=useState(false);
const[showEdu,setOpenEdu]=useState(false);
const[data,setData]=useState({
经验:[{}],
});
const[educations,setEducations]=useState([]);
const[experiences,setExperiences]=useState([]);
const classes=useStyles();
常量radioValues=[{value:'yes',label:'yes'},{value:'no',label:'no'}];
const variables={title:'你是怎么听说我们的?*',typeOfService:'服务类型*'};
const relationOptions=['Walk-In'、'Employee reforter'、'Job Boards'、'Job Fair'、'Social Media'];
const checkBoxLabel=“请注意,您申请这份工作将触发公司对您个人数据的一些处理。有关数据处理的更多信息,请参阅公司的人才获取隐私政策。”;
常量handleChange=({target}:ChangeEvent)=>{
setState({…state,[target.name as keyof typeof state]:target.value});
};
const handleBlur=(事件:任意)=>{
data.experience[0]={…data.experience[0],[event.target.name]:event.target.value};
setData({…data});
};
const-onAddEdu=(edu:any)=>{setEducations([…educations,edu]);setOpenEdu(false);};
const-onAddExp=(exp:any)=>{setExperiences([…experiences,exp]);setOpenExp(false);};
返回(
{console.log(值);}}//eslint禁用行无控制台
render={({handleSubmit})=>(
个人信息
经验
{setOpenExp(!showExp);}}>

当我点击提交按钮时,我只得到了这个日志

这是与教育形式相同的经验形式

我的目标是像这样向结果集中添加经验和教育数组


错误很明显,嵌套了
标记

重现错误的快速示例

const{useState,useffect}=React;
常量应用=()=>{
返回
}
ReactDOM.render(
,
document.getElementById('root'))
);

错误很明显,嵌套了
标记

重现错误的快速示例

const{useState,useffect}=React;
常量应用=()=>{
返回
}
ReactDOM.render(
,
document.getElementById('root'))
);

在使用Material UI门户解决问题之前,我也遇到过类似的情况

    import React from "react";
    import Portal from "@material-ui/core/Portal";

    export default NestedForms = () => {

      const container = React.useRef(null);

      return (
        <>
          <form>
              {/*form content  */}
              <div ref={container} />
              {/*form content  */}
          </form>

          <Portal container={container.current}>
              <form>
                      {/*  otherform */}
              <form/>
          </Portal>
        </>
      )
    }
从“React”导入React;
从“@material ui/core/Portal”导入门户;
导出默认嵌套表单=()=>{
const container=React.useRef(null);
返回(
{/*表单内容*/}
{/*表单内容*/}
{/*其他形式*/}
)
}

在使用Material UI门户解决问题之前,我也遇到过类似的情况

    import React from "react";
    import Portal from "@material-ui/core/Portal";

    export default NestedForms = () => {

      const container = React.useRef(null);

      return (
        <>
          <form>
              {/*form content  */}
              <div ref={container} />
              {/*form content  */}
          </form>

          <Portal container={container.current}>
              <form>
                      {/*  otherform */}
              <form/>
          </Portal>
        </>
      )
    }
从“React”导入React;
从“@material ui/core/Portal”导入门户;
导出默认嵌套表单=()=>{
const container=React.useRef(null);
返回(
{/*表单内容*/}
{/*表单内容*/}
{/*其他形式*/}
)
}

是的,这会影响我为什么不从中获取值吗?我看不到除此之外的任何其他罪魁祸首那么是的,这会影响我为什么不从中获取值吗?我看不到除此之外的任何其他罪魁祸首那么是的