反应形式的输入管理



我正在编写一个动态反应表单。我希望能够打印一个字段值,根据它的值变化来更新状态,当我在字段中输入时。我还想通过单击提交按钮在控制台中打印状态。我知道这并不难,而且我做到了(几乎完美)。我是这样做的:

  • i声明和初始状态,内部和对象称为"输入",有3个属性,名称,电子邮件和密码。
  • 我用一个开关案例声明了我的减速器,动作类型为"setinputs",返回状态和它的输入对象设置为动作负载。
  • 我声明了一个常量"input "赋值给useState,初始值设置为初始状态。
  • 我声明了一个"状态";用我的初始状态初始化useReducer。
  • 然后,我声明了两个函数:handleChange()用于更新"输入"(useState常量)和分派"设置"(setinputs)。有效载荷等于"输入"的动作。handlessubmit()防止提交的默认事件,并在控制台中打印状态。
  • ,最后,对于每个字段,我将value属性设置为相应的"输入";handleChange()函数的onChange。

下面是我的代码:

import React, { useReducer, useState } from 'react'
import './Form.css'
const initialState = {
inputs : {
name: "",
email: "",
password: ""
}
};
const reducer = (state, action) => {
switch(action.type){
case 'SETINPUTS' :
return { ...state, inputs: action.payload };
default: 
return state;
}
}
const Form = () => {
const [inputs, setInputs] = useState(initialState.inputs)
const [state, dispatch] = useReducer(reducer, initialState)

const handleSubmit = (e) => {
e.preventDefault();
console.log(state)
} 
function handleChange(e){
setInputs({ ...inputs, [e.target.name]: e.target.value });
dispatch({ type: 'SETINPUTS', payload: inputs })
}
return (
<div className='form'>
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name</label>
<input 
type="text" 
name='name' 
placeholder='John Doe'
value={inputs.name}
onChange={handleChange}
/>
<label htmlFor="email">Email</label>
<input 
type="email" 
name='email' 
placeholder='johndoe09@example.ex' 
value={inputs.email}
onChange={handleChange}
/>
<label htmlFor="password">Password</label>
<input 
type="password" 
name='password' 
placeholder='enter your password please'
value={inputs.password}
onChange={handleChange}
/>
<button type='submit'>Submit</button>
</form>
<div>
{state.inputs.name} {state.inputs.email} {state.inputs.password}
</div>
</div>
)
}
export default Form

正如您在这张图中看到的,问题是i的类型并不完全是在控制台中返回或打印的内容。我不得不删除最后一个字母,以便为最后一个字母添加一个空格。当我删除最后一个字符时,它仍然存在,等等…真奇怪,我需要你的帮助。

谢谢你!

问题是你的handleChange方法。设置state是一个异步方法…因此,您将无法获得state中的最新值。试试下面的实现:

function handleChange(e) {
setInputs({ ...inputs, [e.target.name]: e.target.value });
}
useEffect(() => {
dispatch({ type: "SETINPUTS", payload: inputs });
}, [inputs]);

或者这个

function handleChange(e) {
setInputs({ ...inputs, [e.target.name]: e.target.value });
dispatch({
type: "SETINPUTS",
payload: {
...inputs,
[e.target.name]: e.target.value
}
});
}

在你的handleChange函数中,setInputs是一个异步操作,这意味着dispatch调用将不会使用输入的最新状态。

你可以直接传入e.target.value:

function handleChange(e){
setInputs({ ...inputs, [e.target.name]: e.target.value });
dispatch({ type: 'SETINPUTS', payload: {...inputs, [e.target.name]: e.target.value }});
}

然而,你可能需要重新考虑你的设计,要么依赖于组件的状态,要么只依赖于reducer存储,而不是同时拥有两者并试图使它们保持同步。

最新更新