我正在编写一个动态反应表单。我希望能够打印一个字段值,根据它的值变化来更新状态,当我在字段中输入时。我还想通过单击提交按钮在控制台中打印状态。我知道这并不难,而且我做到了(几乎完美)。我是这样做的:
- 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存储,而不是同时拥有两者并试图使它们保持同步。