为什么 ReactJs 表单的输入在加载时预填充值不允许再更新它

Why ReactJs form's input prefilled with value on load doesn't allow to update it anymore

我使用的表单应允许用户更新已保存数据的内容。稍后我将现有数据加载到表单输入中,如下所示:-

  <input value={profile.displayName} 
  name="displayName" type="text" 
  placeholder="Display Name" 
  /> // it dosn't work  So I tried next

  <input value={profile.displayName} 
  name="displayName" type="text" 
  placeholder="Display Name" 
  onChange={(e) => {setDisplayName(e.target.value )}}/> // Same issue

那么如何加载现有数据并且数据必须在from中可编辑?

更多说明代码:- 我正在使用这样的钩子:-

const [profile, setProfile] = useState({});

useEffect(() => {

if (props.match.params.title) {
  setTitle(props.match.params.title);
} else if (props.location.state.title) {
  setTitle(props.location.state.title);
}

if (props.location.state) {
  if (props.location.state.profile) {
    setProfile(props.location.state.profile)
    console.warn("profile: ", props.location.state.profile)
  }
}

}

因此配置文件作为道具来自另一个组件。这部分很好。也可以将数据加载到表单中。但是加载数据后,我不能再编辑它了。

假设你有一个像下面这样的钩子

const [displayName, setDisplayName] = useState('');

在useEffect中设置profile的同时也设置了display name。

setDisplayName(props.location.state.profile.displayName)

最好在 const

中破坏配置文件
const  { profile } = props.location.state;

最后在输入

    <input value={displayName} name="displayName" type="text" placeholder="Display Name" onChange={(e) => {setDisplayName(e.target.value )}}/>

您将初始配置文件设置为空对象,但将输入的默认值分配给 profile.displayName,即 undefined,React 将抛出以下警告。

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.*

你的初始对象应该是这样的

const [profile, setProfile] = useState({
  displayName: ""
});

然后像

一样更新值
<input
  value={profile.displayName}
  name="displayName"
  type="text"
  onChange={e => {
    setProfile({ ...profile, displayName: e.target.value });
  }}
/>

// Get a hook function
const {useState, useEffect} = React;

function App() {
  const [profile, setProfile] = useState({
    displayName: "",
    gender: "",
    occupation: ""
  });

  useEffect(() => {
    setProfile({
      displayName: "Whosebug",
      gender: "Male",
      occupation: "Software Eng."
    });
  }, []);

  return (
    <div>
      <input
        value={profile.displayName}
        name="displayName"
        type="text"
        onChange={e => {
          setProfile({ ...profile, [e.target.name]: e.target.value });
        }}
      />
      <input
        value={profile.gender}
        name="gender"
        type="text"
        onChange={e => {
          setProfile({ ...profile, [e.target.name]: e.target.value });
        }}
      />

      <input
        value={profile.occupation}
        name="occupation"
        type="text"
        onChange={e => {
          setProfile({ ...profile, [e.target.name]: e.target.value });
        }}
      />

      <p>display name: {profile.displayName}</p>
      <p>gender: {profile.gender}</p>
      <p>occupation: {profile.occupation}</p>
    </div>
  );
}
// Render it
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>