You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Formik文本框重置问题:解决Redux容器组件联动Formik表单时点击按钮无法清空输入框的方案

解决Formik提交后输入框无法清空的问题

我来帮你搞定这个问题!你现在的核心问题是同时混用了Redux容器组件的state和Formik内部状态,导致两者状态不同步——提交后父组件的taskText清空了,但Formik的输入状态没跟上,所以输入框看起来没变化。咱们一步步来修复:

先分析原代码的问题点

  1. 在TaskInput里,你初始化了Formik的initialValues,但之后输入框的value和onChange都绑定到了父组件的属性,等于Formik的状态完全没被用到,成了摆设。
  2. Formik的initialValues只会在组件挂载时初始化一次,后续父组件的value变化不会自动同步到Formik内部状态。
  3. 提交时你只清空了父组件的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:07:30