简体   繁体   中英

Warning: A component is changing a controlled input to be uncontrolled in React js

HELP. i use react hook, i got the error when i type the input.

error:

Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Code:

const AddUser = () => {
const initialUserState = {
    id: null,
    name: '',
    age: 0
}

const [users, setUsers] = useState(initialUserState)

const handleChange = (e) => {
    setUsers({ [e.target.name]: e.target.value })

    e.preventDefault()
}    

return (
    <div>
        <input name="name" type="text" value={users.name} onChange={handleChange}/>
        <input name="age" type="number" value={users.age} onChange={handleChange}/>
    </div>
)}

Unlike setting the state in a class component, useState doesn't merge the object you pass, and you have to do it manually when setting the state. When you set age , for example, you replace the entire state object, which makes name to be undefined , and vice versa.

Use functional update , and create a new state based on the previous state object before setting it.

 const { useState } = React const AddUser = () => { const initialUserState = { id: null, name: '', age: 0 } const [users, setUsers] = useState(initialUserState) const handleChange = (e) => { // create the new state and set it setUsers(prev => ({...prev, [e.target.name]: e.target.value })) e.preventDefault() } return ( <div> <input name="name" type="text" value={users.name} onChange={handleChange}/> <input name="age" type="number" value={users.age} onChange={handleChange}/> </div> ) } ReactDOM.render( <AddUser />, root )
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

This page and this paragraph can help you understand the problem.

When you get the updated input through the onChange event listener you don't need to pass again the data through the value attribute.

When data is passed through the value attribute the component is considered "controlled". This means that the component is controlled by your code and shouldn't receive user input.

If you just want to set a default value you can use the defaultValue attribute.

To remove the warning just remove the value={/* Something */} .

in my case, i figured out changing input atribute name from:

<div>
     <input name="name" type="text" value={users.name} onChange={handleChange}/>
     <input name="age" type="number" value={users.age} onChange={handleChange}/>
</div>

to:

    <div>
         <input name="fullname" type="text" value={users.fullname} onChange={handleChange}/>
         <input name="age" type="number" value={users.age} onChange={handleChange}/>
    </div>

for example in this i change name for fullname, due to react does not recognize it as a constant but as the attribute of the input

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM