Home > Software design >  How to make inputs validate and save their state at same time?
How to make inputs validate and save their state at same time?

Time:10-22

i'm working on Register validation form using React-Hook-Form. My problem is stateRegister is no more handle the inputs state and it looks like my form is deprecated.

Here is my demo on stackblitz: https://stackblitz.com/edit/react-ktikva

As you can see that validation is working fine, but using console.log i no more see my inputs state that i already set...

How to make inputs validate and save their state at same time?

Edit: i noticed that handleChange doesn't work after applying react-hook-form.

import * as React from 'react'
import Grid from '@mui/material/Grid'
import Typography from '@mui/material/Typography'
import TextField from '@mui/material/TextField'
import FormControlLabel from '@mui/material/FormControlLabel'
import Checkbox from '@mui/material/Checkbox'
import { useState } from 'react'
import propTypes from 'prop-types'
import { useForm } from 'react-hook-form'

const initialValues = {
  username: '',
  login: '',
  password: '',
}

export default function BasicForm(props) {
  const [stateRegister, setStateRegister] = useState(initialValues)
  const [repassword, setRepassword] = useState('')
  const {
    register,
    formState: { errors },
  } = useForm({
    mode: 'all',
  })

  console.log('errors: ', errors)

  const handleChange = (e) => {
    props.stateOfRegister(stateRegister)
    setStateRegister({
      ...stateRegister,
      [e.target.name]: e.target.value,
    })
    console.log('input:', e.target.value)
    console.log('state: ', stateRegister)
  }

  const handleConfirmPassword = (e) => {
    setRepassword({
      ...repassword,
      [e.target.name]: e.target.value,
    })
    console.log(repassword)
    if (repassword === stateRegister.password) {
      console.log('matched')
    }
  }

  return (
    <React.Fragment>
      <Typography variant="h6" gutterBottom>
        Register your informations
      </Typography>
      <Typography variant="caption" color="red" gutterBottom>
        All champs are required *
      </Typography>
      <Grid container spacing={3}>
        <Grid item xs={12}>
          <TextField
            required
            id="username"
            name="username"
            label="Username"
            fullWidth
            autoComplete="username"
            variant="standard"
            onChange={(e) => handleChange(e)}
            {...register('username', {
              required: 'Username is required',
              minLength: { value: 3, message: 'Username must be at least 3 characts long' },
              maxLength: { value: 30, message: 'Username must be at most 30 characts long' },
            })}
            helperText={errors.username?.message}
          />
        </Grid>
        <Grid item xs={12}>
          <TextField
            required
            id="login"
            name="login"
            label="Email"
            type="email"
            fullWidth
            autoComplete="email"
            variant="standard"
            onChange={(e) => handleChange(e)}
            {...register('login', {
              required: 'Email is required',
              pattern: {
                value:
                  /^(([^<>()[\]\\.,;:\s@"] (\.[^<>()[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/,
                message: 'Email must be valid',
              },
            })}
            helperText={errors.login?.message}
          />
        </Grid>
        <Grid item xs={12}>
          <TextField
            required
            id="password"
            name="password"
            label="Password"
            type="password"
            minLength="8"
            fullWidth
            autoComplete="password"
            variant="standard"
            onChange={(e) => handleChange(e)}
            {...register('password', {
              required: 'Password is required',
              pattern: {
                value: /^(?=.*[0-9])(?=.*[!@#$%^&*.,])[a-zA-Z0-9!@#$%^&*.,]{6,16}$/,
                message:
                  'Password must contain At least 6 Characters, One Uppercase, One Lowercase, One Number and One Special Case Character',
              },
            })}
            helperText={errors.password?.message}
          />
          {stateRegister.password}
        </Grid>
        <Grid item xs={12}>
          <FormControlLabel
            control={<Checkbox color="secondary" name="saveLogin" value="yes" />}
            label="Keep me logged in"
          />
        </Grid>
      </Grid>
    </React.Fragment>
  )
}

BasicForm.propTypes = {
  stateOfRegister: propTypes.func,
}

CodePudding user response:

you can use watch() and getValues() methods for show input values on every change:

const { watch } = useForm();

  React.useEffect(() => {

    const subscription = watch((value, { name, type }) => {
    console.log(value, name, type))}

    return () => subscription.unsubscribe();
  }, [watch]);

also for more information you can read this parts of document here:

  1. https://react-hook-form.com/api/useform/watch/
  2. https://react-hook-form.com/api/useform/getvalues/
  • Related