【问题标题】:Warning: A component is changing a controlled input to be uncontrolled in React js警告:组件正在将受控输入更改为在 React js 中不受控制
【发布时间】:2021-07-29 12:29:03
【问题描述】:

帮助。我使用反应钩子,当我输入输入时出现错误。

错误:

警告:组件正在将受控输入更改为不受控制。这可能是由于值从已定义更改为未定义引起的,这不应该发生。决定在组件的生命周期内使用受控输入元素还是不受控输入元素。

代码:

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>
)}

【问题讨论】:

  • 你的句柄改变只是设置了名字或者年龄,所以其他的变成未定义的。如果您只想更改对象中的一个属性,请尝试使用扩展语法。或者对年龄和姓名使用单独的状态。
  • 这不是错误,而是警告。

标签: javascript reactjs react-hooks


【解决方案1】:

与在类组件中设置状态不同,useState 不会合并你传递的对象,设置状态时必须手动进行。例如,当您设置age 时,您会替换整个状态对象,这会使name 变为undefined,反之亦然。

使用functional update,并在设置前根据之前的状态对象创建一个新状态。

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>

【讨论】:

    【解决方案2】:

    This pagethis paragraph 可以帮助您理解问题。

    当您通过onChange 事件侦听器获取更新的输入时,您无需再次通过value 属性传递数据。

    当数据通过value 属性传递时,组件被视为“受控”。这意味着组件由您的代码控制,不应接收用户输入。

    如果您只想设置默认值,可以使用defaultValue 属性。

    要删除警告,只需删除 value={/* Something */}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 2023-03-05
      • 2018-01-13
      • 2020-08-06
      • 2019-06-03
      • 1970-01-01
      • 2017-09-23
      相关资源
      最近更新 更多