如何触发onSubmit的最终表单?

时间:2019-12-30 15:33:39

标签: html reactjs typescript forms react-final-form

我对React Final Form有问题。我尝试遵循官方文档中的示例,但是我仍然不明白为什么我的表单不希望调用onSubmit作为示例,并且我仍在尝试理解handlesubmit的作用。

我认为问题在于我的字段是从另一个使用useField挂钩的组件中调用的。

import React, { FC } from 'react'
import { Form, Field } from 'react-final-form'
import {
  Grid,
  Box,
  Button,
  createStyles,
  makeStyles,
  Theme,
} from '@material-ui/core'
import { render } from 'react-dom'
import InputField from './InputField'

interface InputFinalFormModalProps {
  fieldsValue: { title: string; value: string }[]
}

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    annullaBtn: {
      backgroundColor: '#fff',
      border: `1px solid ${theme.palette.secondary.main}`,
      color: theme.palette.secondary.main,
      fontFamily: 'HouschkaHead',
      fontSize: '17px',
      fontWeight: 'bold',
      paddingLeft: '40px',
      paddingRight: '40px',
      marginRight: '15px',
    },
    salvaBtn: {
      fontFamily: 'HouschkaHead',
      fontSize: '17px',
      fontWeight: 'bold',
      paddingLeft: '40px',
      paddingRight: '40px',
      marginLeft: '15px',
    },
    row: {
      width: '100%',
      textAlign: 'end',
    },
    container: {
      '& > .MuiGrid-item': {
        paddingBottom: '20px',
        paddingTop: '0px',
        paddingLeft: '11px',
        paddingRight: '11px',
      },
    },
  })
)

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

const onSubmit = async (values: {}) => {
  await sleep(300)
  console.log(JSON.stringify(values))
}

const validate = (values: {}) => {
  const errors = {message: ''}
   if (!Object.values(values).toString()) {
         errors.message = "Required";
       }  

  return errors
}

const InputFinalFormModal: FC<InputFinalFormModalProps> = ({ fieldsValue }) => {
  const classes = useStyles()
  return (
    <Form
      onSubmit={onSubmit}
      validate={validate}
      render={({ handleSubmit, form, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <Grid container className={classes.container}>
            {fieldsValue.map((field) => {
              return (
                <InputField title={field.title} value={field.value} />
              )
            })}
            
          </Grid>
          <Box className={classes.row} mt="20px">
            <Button className={classes.annullaBtn}>Annulla</Button>
            <Button
              type="submit"
              onClick={() => onSubmit(values)}
              className={classes.salvaBtn}
              disabled={submitting || pristine}
            >
              Salva
            </Button>
          </Box>
          {/* <button
            type="submit"
            onClick={() => onSubmit(values)}
            disabled={submitting || pristine}
          >
            Submit
          </button>
          <button
            type="button"
            onClick={form.reset}
            disabled={submitting || pristine}
          >
            Reset
          </button> 
          <pre>{JSON.stringify(values)}</pre>*/}
        </form>
      )}
    />
  )
}

InputFinalFormModal.displayName = 'InputFinalFormModal'

export default InputFinalFormModal

这是我关于inputField的摘录

import React, { FC, useEffect, useState } from 'react'
import { useField } from 'react-final-form'
import {
  Box,
  Grid,
  createStyles,
  makeStyles,
  Theme,
  withStyles,
} from '@material-ui/core'
import InputLabel from '@material-ui/core/InputLabel'
import InputBase from '@material-ui/core/InputBase'
import { parse } from 'path'

interface InputFieldProps {
  title: string
  value: string
}


const BootstrapInput = withStyles((theme: Theme) =>
  createStyles({
    input: {
      borderRadius: 4,
      position: 'relative',
      backgroundColor: theme.palette.common.white,
      border: '1px solid #bdc7d3',
      width: '100%',
      padding: '10px 12px',
      transition: theme.transitions.create(['border-color', 'box-shadow']),
      // Use the system font instead of the default Roboto font.
      fontFamily: 'Montserrat',
      fontSize: '14px',
      lineHeight: '1.21',
      fontWeight: 'normal',
      color: theme.palette.text.primary,
      '&:focus': {
        boxShadow: 'inset 0 0 12px 4px rgba(0, 179, 152, 0.05)',
        borderColor: theme.palette.secondary.main,
      },
    },
  })
)(InputBase)

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    inputTitle: {
      color: '#7C92A8',
      fontSize: '19px',
      lineHeight: 1.76,
      transition: 'font-weight 0.5s, color 0.5s',
      '&.Mui-focused': {
        color: theme.palette.secondary.main,
        fontWeight: 'bold',
      },
    },
    requiredText:{
      color: 'red'
    }
  })
)

const InputField: FC<InputFieldProps> = ({ title, value}) => {
  let {input, meta} = useField(title)
  const classes = useStyles()
  let [handleValidate, setHandleVlidate] = useState(false)
  let [required, setRequired] = useState('')

  useEffect(() => {
   if(parseInt(value)){
     setRequired('valore non valido')
     setHandleVlidate(true)
     /* if(isNaN(input.value)){
     } */
   }else{

     if(!input.value){
       setRequired('Campo Obbligatorio')
       setHandleVlidate(true)  
     }
   }
  },[input.value])


  return (
    <Grid item xs={12} md={6}>
      <InputLabel
        shrink
        htmlFor="bootstrap-input"
        className={classes.inputTitle}
      >
        {title}
      </InputLabel>
      <BootstrapInput
        {...input}
        defaultValue={value}
        id="bootstrap-input"
        placeholder={value}
      />
       {meta.touched && !input.value && (
<span className={classes.requiredText}>{required}</span>
      )}
    </Grid>
    /*    <Grid item xs={6} lg={6}>
      <Box>
        <label className={classes.inputTitle} onClick={() => console.log('check')}>{title}</label>
      </Box>
      <input {...field.input} className={classes.inputField} placeholder={value} />
      {field.meta.touched && field.meta.error && (
        <span>{field.meta.error}</span>
      )}
        </Grid> */
  )
}

InputField.displayName = 'InputField'

export default InputField

1 个答案:

答案 0 :(得分:0)

如果您的表单有效,则验证功能需要返回{},而不是{ message: '' }