有没有一种方法可以使用一个事件处理程序更新多个useState(反应挂钩)或一个useState(反应挂钩)的多个属性?

Rak*_*din 0 reactjs react-hooks

我正在使用2个字段登录表单。电子邮件和密码。当我使用代表两个字段的2 useState时,然后当我使用handleChange更新状态时,两个状态都将更新。这不是意图。

   const [email, setEmail] = useState()
   const [password, setPassword] = useState()

    const handleChange = e => {
        const {value} = e.target
        setEmail(value)
        setPassword(value)
    }
Run Code Online (Sandbox Code Playgroud)

我不想使用多个事件处理程序来处理每个输入字段。我试过了

    const [state , setState] = useState({
        email : "",
        password : ""
    })

    const handleChange = e => {
        const {name , value} = e.target
        setState({
            [name] : value
        })
    }
Run Code Online (Sandbox Code Playgroud)

但这会一次更新一个属性。并且其他财产价值迷失了。因此,有什么方法可以像使用状态组件那样用一个事件处理程序更新所有输入字段。

    this.state = {
      email : "",
      password : ""
    }

    const handleChange = e => {
        const {name , value} = e.target
        this.setState({
           [name] : value
        })
    }
Run Code Online (Sandbox Code Playgroud)

Doğ*_*acı 20

您应该将 setState 与回调函数一起使用:

setState(prev => ({ 
    ...prev,
    email: 'new mail',
}))
Run Code Online (Sandbox Code Playgroud)

您将创建一个新的 state 对象,该对象由以前的 state 创建。你可以覆盖任何你需要的东西。如果您有一个复杂的状态对象,则需要更多的新对象。


Sak*_*oBu 9

您可以像这样创建自定义钩子:

import { useState } from 'react';

export const useForm = (initialValues) => {
  const [values, setValues] = useState(initialValues);

  return {
    values,
    handleChange: (e) => {
      setValues({
        ...values,
        [e.target.name]: e.target.value,
      });
    },
    reset: () => setValues(initialValues),
  };
};
Run Code Online (Sandbox Code Playgroud)

然后以任何形式使用它(例如):

export default function SignInForm() {
    const { values, handleChange, reset } = useForm({ username: '', password: '' });

    const handleSubmit = e => {
        e.preventDefault();
        reset();
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type='text'
                name='username'
                placeholder='Enter your username...'
                onChange={handleChange}
                value={values.username}
            />
            <input
                type='password'
                name='password'
                placeholder='Enter your password...'
                onChange={handleChange}
                value={values.password}
            />
            <button type='submit'>
                Sign In
            </button>
        </form>
    );
}
Run Code Online (Sandbox Code Playgroud)


Rak*_*din 5

感谢Do?ancan Arabac?。我试图模仿基于类的组件的state和setState,所以感觉不会改变。我的解决方案如下所示。

const [state , setState] = useState({
    email : "",
    password : ""
})

const handleChange = e => {
    const {name , value} = e.target
    setState( prevState => ({
        ...prevState,
        [name] : value
    })
}
Run Code Online (Sandbox Code Playgroud)