React Formik文本框重置问题:解决Redux容器组件联动Formik表单时点击按钮无法清空输入框的方案
解决Formik提交后输入框无法清空的问题
我来帮你搞定这个问题!你现在的核心问题是同时混用了Redux容器组件的state和Formik内部状态,导致两者状态不同步——提交后父组件的taskText清空了,但Formik的输入状态没跟上,所以输入框看起来没变化。咱们一步步来修复:
先分析原代码的问题点
- 在
TaskInput里,你初始化了Formik的initialValues,但之后输入框的value和onChange都绑定到了父组件的属性,等于Formik的状态完全没被用到,成了摆设。 - Formik的
initialValues只会在组件挂载时初始化一次,后续父组件的value变化不会自动同步到Formik内部状态。 - 提交时你只清空了父组件的state,但没触发Formik的状态重置,导致输入框显示的还是Formik里留存的旧值。
方案1:让Formik完全接管输入状态(推荐)
这种方式最简洁,把输入框的状态完全交给Formik管理,父组件只负责处理添加任务的逻辑:
修改TaskInput.jsx
import { useFormik } from 'formik'; export const TaskInput = ({ onAdd }) => { const formik = useFormik({ initialValues: { text: '', // 直接初始化空值,不需要从父组件传value }, onSubmit: (values, { resetForm }) => { // 把输入的值传给父组件的添加方法 onAdd(values.text); // 提交成功后调用resetForm清空Formik状态,输入框自动清空 resetForm(); }, }); return ( <Container> {/* 不需要外层的Formik组件,useFormik钩子已经足够 */} <FormWrapper onSubmit={formik.handleSubmit}> <Input id="task" type="text" placeholder="Add a task" value={formik.values.text} onChange={formik.handleChange} /> <AddButton type="submit">Add</AddButton> </FormWrapper> </Container> ); };
修改Task.jsx容器组件
去掉自己维护的taskText状态,逻辑更简洁:
class Task extends PureComponent { handleAddTask = (taskText) => { const { addTask } = this.props; // 直接使用Formik传过来的任务文本 addTask(uuidv4(), taskText, false); // 这里不需要再清空state,Formik已经处理了输入框清空 }; render() { return ( <> {/* 只需要传递添加任务的方法,不需要value和onChange */} <TaskInput onAdd={this.handleAddTask} /> ... </> ); } } const mapStateToProps = ({ tasks }) => { return { tasks, }; }; export default connect(mapStateToProps, { addTask, removeTask, completeTask, editTask })(Task);
方案2:保留父组件state(特殊需求场景)
如果你因为其他逻辑必须保留父组件的taskText状态,可以通过监听父组件的value变化,同步更新Formik的状态:
修改TaskInput.jsx
import { useFormik, useEffect } from 'formik'; export const TaskInput = ({ value, onAdd }) => { const formik = useFormik({ initialValues: { text: value, }, onSubmit: (values, { resetForm }) => { onAdd(values.text); // 重置Formik状态 resetForm(); }, }); // 监听父组件value变化,同步到Formik useEffect(() => { formik.setFieldValue('text', value); }, [value, formik]); return ( <Container> <FormWrapper onSubmit={formik.handleSubmit}> <Input id="task" type="text" placeholder="Add a task" value={formik.values.text} onChange={formik.handleChange} /> <AddButton type="submit">Add</AddButton> </FormWrapper> </Container> ); };
对应的Task.jsx修改
保留taskText状态,提交后清空:
class Task extends PureComponent { constructor(props) { super(props) this.state = { taskText: '', } } handleAddTask = (taskText) => { const { addTask } = this.props; addTask(uuidv4(), taskText, false); // 清空父组件state,会触发TaskInput的useEffect同步Formik状态 this.setState({ taskText: '' }); }; render() { const { taskText } = this.state return ( <> <TaskInput onAdd={this.handleAddTask} value={taskText} /> ... </> ); } }
内容的提问来源于stack exchange,提问作者qwfrjk
相关产品推荐
相关产品推荐

