javascript (ReactJS)“警告:组件正在改变要控制的不受控输入,这可能是由于值从undefined更改...”

j8ag8udp  于 2023-05-05  发布在  Java
关注(0)|答案(4)|浏览(166)

由另一个控制器控制的UserForm在控制台上抱怨为
“警告:组件正在更改要控制的非受控输入。这可能是由于值从undefined更改为已定义的值而导致的,而这是不应该发生的。决定在部件的使用寿命内使用受控或非受控输入元件。More info:https://reactjs.org/link/controlled-components input span li ul..."**
以下是组件代码:

export default({user}) => {
  if(!user) {
    return <div></div>
  } else {
    const [name,setName] = useState(user.name|| "")
    useEffect(() => {
      setName(user.name);
    }, [user])
              
    return <form>
             <fieldset> 
               <legend> Edit  {user.name }</legend>
               <p> 
                 <label htmlFor={"name"}> Name  </label>
                 <input  id="name" value={name || ""} onChange={e => setName(e.target.value)} />
               </p> 
             </fieldset>
           </form>
  }
}

我尝试了其他stackoverflow答案建议的所有修复,但仍然给出警告。
我是不是漏掉了什么?

qco9c6ql

qco9c6ql1#

实际上在React当你面对这个,这是一个错误的控制和不受控制的组件,在简单的话:受控组件:是使用状态来更改其值的组件。示例

<input
onChange={(e)=>{whatever!}
value={from your state}
/>

而在不受控制的组件中,状态并不涉及那么多,您可以简单地使用defaultValue或ref。示例

<input
defaultValue={from your state or from anywhere}
/>

**记住:**如果你同时使用value和defaultValue,它会给予你错误,因为我们不能同时使用受控组件的value和非受控组件的defaultValue。

提示:你需要在受控和非受控组件之间进行选择,所以使用ref将是解决方案。将value更改为defaultValue将解决此问题。

注:

defaultValue仅用于初始负载。如果你想初始化输入,那么你应该使用defaultValue,但是如果你想使用state来改变值,那么你需要使用value。阅读本文了解更多React输入defaultValue不随状态更新
我在输入中使用了下面的方法来消除该警告,通过使用Short-circuit求值来定义value属性,如下所示:

value={this.state.fields.name || ''}   // (undefined || '') = ''

另一种方法

原因是,在您定义的状态中:

this.state = { fields: {} }

字段作为空白对象,因此在第一次渲染期间this.state.fields.name将是undefined,并且输入字段将获得其值为:

value={undefined}

因此,输入字段将变得不受控制。
在input中输入任何值后,fields的状态将更改为:

this.state = { fields: {name: 'xyz'} }

此时输入字段被转换为受控组件;这就是为什么你会得到错误:
组件正在更改要控制的文本类型的非受控输入。

可能的解决方案:

1-将fields的状态定义为:

this.state = { fields: {name: ''} }
zpqajqem

zpqajqem2#

我已经用这个工作示例更新了您的组件。

const { useEffect, useState } = React;

function Example({ user }) {

  const [name, setName] = useState(user.name);

  function handleChange(e) {
    setName(e.target.value);
  }

  useEffect(() => console.log(name), [name]);

  if(!user) return <div></div>;

  return (
    <form>
      <fieldset> 
        <legend>Edit name</legend>
        <input
          id="name"
          value={name}
          onChange={handleChange}
        />
      </fieldset>
    </form>
  )
};

const user = { name: 'Bob' };

ReactDOM.render(
  <Example user={user} />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
r7xajy2e

r7xajy2e3#

这个问题主要发生在你有一个未定义的属性值时,现在它可以是checked<input />字段或type甚至value属性。

**解决方案:**添加默认值||

<input checked={state.bestSellerOnly || false} id="best-seller" type="checkbox" value="" className="" />

这里state.bestSellerOnly可能会在挂载时返回undefined,这可能会导致react警告。

polkgigr

polkgigr4#

如果你有你的初始值undefined你可以使用或符号回退到一个初始的空字符串。

const [someValue, setValue] = useState<string | undefined>();
...
<input
  value={someValue ?? ''}
  onChange={e => setValue(e.target.value)}
/>

相关问题