Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debounce Formik Field ReactJS

I want to debounce Formik <Field/> but when I type in the field seems debounce does not work. Also I have tried lodash.debounce, throttle-debounce and the same result. How to solve this?

CodeSandbox - https://codesandbox.io/s/priceless-nobel-7p6nt

Snippet:

import ReactDOM from "react-dom";
import { withFormik, Field, Form } from "formik";

const App = ({ setFieldValue }) => {
  let timeout;
  const [text, setText] = useState("");

  const onChange = text => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => setText(text), 750);
  };

  return (
    <Form>
      <Field
        type="text"
        name="textField"
        placeholder="Type something..."
        onChange={e => {
          onChange(e.target.value);
          setFieldValue("textField", e.target.value);
        }}
        style={{ width: "100%" }}
      />
      <br />
      <br />
      <div>output: {text}</div>
    </Form>
  );
};

const Enhanced = withFormik({
  mapPropsToValues: () => ({
    textField: ""
  }),
  handleSubmit: (values, { setSubmitting }) => {
    setSubmitting(false);
    return false;
  }
})(App);

ReactDOM.render(<Enhanced />, document.getElementById("root"));
like image 212
Arthur Avatar asked Sep 05 '25 16:09

Arthur


2 Answers

  const [text, setText] = useState("");
  const [t, setT] = useState(null);

  const onChange = text => {
    if (t) clearTimeout(t);
    setT(setTimeout(() => setText(text), 750));
  };
like image 157
Skyrocker Avatar answered Sep 08 '25 11:09

Skyrocker


I would like to suggest to move the call inside of timeout function.

const App = ({ setFieldValue }) => {
      let timeout;
      const [text, setText] = useState("");

      const onChange = text => {
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
          setText(text);
          //changing value in container
          setFieldValue("textField", text);
        }, 750);
      };

      return (
        <Form>
          <Field
            type="text"
            name="textField"
            placeholder="Type something..."
            onChange={e => {
              onChange(e.target.value);
            }}
            style={{ width: "100%" }}
          />
          <br />
          <br />
          <div>output: {text}</div>
        </Form>
      );
    };
like image 45
Victor Manuel Buil Vicente Avatar answered Sep 08 '25 10:09

Victor Manuel Buil Vicente