Search code examples
reactjsonchangeobject-literalcontrolled-component

ReactJS:Input on controlled component doesn't change state


I have an object literal with some empty values that I want to change according to a list of inputs. The problem is that, though the value of the input is updated with a predefined value in useEffect(), I can't change the input with the onChange handler. This is what I have:

const userValues = {
  username:'',
  city:'',
  country:'',
  description:''
}

function Comp(){
 const  [details, setDetails] = useState(userValues)

 useEffect(() => {
    setUserDetails()
  }, [details])

async function setUserDetails() {
      setDetails({...details,
      username: "username",
      country: "country",
      city: "city"
      })
}
const handleInputChange = (e) =>{
    const {name,value} = e.target
    setDetails({
      ...details,
      [name]:value
    })

   <Input fontSize="20px" w="sm" mr={5} fontWeight="bold" textAlign="center" 
               value={details.username} onChange={(e)=>handleInputChange(e)}/>
}

I have also tried to set the value directly in the onChange event

onChange={(e)=>setDetails({...details,[e.target.name]:e.target.value})}} 

but the input won't change from the default value. Maybe someone can point me into the right direction. I followed this tutorial https://dev.to/deboragaleano/how-to-handle-multiple-inputs-in-react-55el Any help would be appreciated!


Solution

  • You have to set the correct name attribute to you input element e.g.:

      return (
        <Input
    
          name="userName"
          value={details.username}
    
          fontSize="20px"
          w="sm"
          mr={5}
          fontWeight="bold"
          textAlign="center"
          onChange={(e) => handleInputChange(e)}
        />
      )
    

    The second issue is the following effect:

    useEffect(() => {
        setUserDetails()
      }, [details])
    

    This code will reset details whenever details changes.
    You will have to delete this effect or at least remove details from the dependency array e.g.:

    const  [details, setDetails] = useState(() => {
      return {
          username: "username",
          country: "country",
          city: "city"
      };
    });
    

    or

    useEffect(() => {
        setUserDetails()
      }, [])