React中如何使用useState存储和更新多个值?

41

我有一系列用户数据元素,我正在使用React hooks在组件内收集这些元素。

const [mobile, setMobile] = useState('');
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');

每个这些都会按以下方式更新。

<input type="text"
       className="form-control"
       id="mobile"
       placeholder="Enter a valid mobile number"
       onChange={event => {setMobile(event.target.value)}}/>

使用对象作为变量有更简洁的方法吗?


1
当然,你可以使用对象作为变量。const [values, setValues] = useState({ mobile: "", ... }); - jonrsharpe
@jonrsharpe 我该如何在单独的 onChange 事件中调用 set 方法? - Melissa Stewart
2
setValues({ ...values, [prop]: newValue }); 的翻译是什么? - jonrsharpe
3个回答

84

你应该给输入标签添加name属性。每个名字必须与AllValues对象中的键匹配。

const [allValues, setAllValues] = useState({
   mobile: '',
   username: '',
   email: '',
   password: '',
   confirmPassword: ''
});
const changeHandler = e => {
   setAllValues({...allValues, [e.target.name]: e.target.value})
}
return (
   <input type="text"
       className="form-control"
       id="mobile"
       name="mobile"
       placeholder="Enter a valid mobile number"
       onChange={changeHandler}
   />
   // ...
)

2
我不明白为什么[e.target.name]必须放在[]里面? - Mohammad Kermani
11
这是使用变量(e.target.name)名称添加对象键的方法。 - Shotiko Topchishvili
为什么我们应该使用名称而不是ID?只是惯例吗? - Dinis Rodrigues
1
因为ID必须是唯一的,而多个元素可以具有相同的名称。 - Shotiko Topchishvili
TS7006: Parameter 'e' implicitly has an 'any' type. - Dr.jacky
TS7006: Parameter 'e' implicitly has an 'any' type. - undefined

22

上述答案在某些情况下可能会引起问题,以下是正确的方法。

const [allValues, setAllValues] = useState({
   mobile: '',
   username: '',
   email: '',
   password: '',
   confirmPassword: ''
});
const changeHandler = e => {
   setAllValues( prevValues => {
   return { ...prevValues,[e.target.name]: e.target.value}
}
}

1
这个答案应该比被接受的答案更安全。我经历过一些棘手的 bug,而这个答案解决了那个问题。 - Thanh Nguyen
对于 React 16 及更早版本,这可能会因事件池而导致问题。请确保仅在 React 17 或更高版本中使用此方法。请注意,您仍然可以使用此答案,并添加一些额外的行,例如 <_name=e.target.name;_value=e.target.value>,并在返回语句中使用 _name 和 _value 而不是直接使用 e。 - JM217

7

设置初始值

const initialValues = {                   // type all the fields you need
name: '',
email: '',
password: ''
};

UseState

const [values, setValues] = useState(initialValues);       // set initial state

Handling the changes

const handleChange = (e) => {                
  setValues({
    ...values,                                // spreading the unchanged values
    [e.target.name]: e.target.value,          // changing the state of *changed value*
  });
};

Making the Form

<form>
  <input type="email"
   id="xyz"
   name="email"                                     // using name, value, onChange for applying changes
   value={email}
   onChange={changeHandler}
   placeholder="Enter your email"
   />
   // other inputs
</form>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接