Home > Software engineering >  Reference a component after removing & re-adding React
Reference a component after removing & re-adding React

Time:08-08

When I remove the component by toggling the boolean value (in this case 'someBooleanValue'), the component is removed as well as the reference in formConfirmPassword. When I re-add the component, the reference is gone which throws an error (as it should)

So basically, how would I go about fixing this so that I may remove and add the component without throwing an error? The following code should clear the question:

import { useRef } from "react";
import TextField from '@mui/material/TextField';

const HomePage = () => {

  const formEmail = useRef('')
  const formPassword = useRef('')
  const formConfirmPassword = useRef('')

  return(
    <>

    <TextInput ref={formEmail} id="email" label="Email" variant="standard" />

    <TextField inputRef={formPassword} id="password" label="Password" variant="standard" type="password" />

    {
      someBooleanValue
      ?<TextField inputRef={formConfirmPassword} error={formPassword.current.value !== formConfirmPassword.current.value} helperText={formPassword.current.value !== formConfirmPassword.current.value ? 'Passwords do not match' : '' } id="confirm-password" label="Confirm Password" variant="standard" type="password" />
      :null
    }
    </>
  )

}

CodePudding user response:

This is a sort of chicken and egg situation. When you unmount the component, react sets formConfirmPassword.current to null. When you mount it again, it populates it -- however crucially, this actually happens after it tries to access it to pass down in your error and helperText props.

refs attached to components are only set once they already rendered -- at which point its too late as the code has errored since its null on the initial pass.

Your main problem here is refs aren't really suitable for what you are trying to do -- which is react to changes in the formPassword and formConfirmPassword values. You need to use state here instead so that the data sticks around when it unmounts. Also, this will ensure that when formPassword or formConfirmPassword changes your error/helpertext props will re-evaluate. When a ref value changes, it doesnt trigger a rerender which means your error prop for example wont automatically recalculate as the user types if you use a ref.

import { useRef } from "react";
import TextField from '@mui/material/TextField';

const HomePage = () => {

  const [formEmail, setFormEmail] =  useState('')
  const [formPassword, setFormPassword ] =  useState('')
  const [formConfirmPassword, setFormConfirmPassword] = useState('')

  return(
    <>

    <TextInput id="email" label="Email" variant="standard" onChange={(e) => setFormEmail(event.target.value) } value={formEmail}/>

    <TextField id="password" label="Password" variant="standard" type="password" onChange={(e) => setFormPassword(event.target.value) } value={formPassword}/>

    {
      someBooleanValue
      ?<TextField error={formPassword !== formConfirmPassword} helperText={formPassword !== formConfirmPassword ? 'Passwords do not match' : '' } id="confirm-password" label="Confirm Password" variant="standard" type="password"  onChange={(e) => setFormConfirmPassword(event.target.value) } value={formConfirmPassword}/>
      :null
    }
    </>
  )

}
  • Related