xnimorz/use-debounce

Awkward delay using the input property value

Closed this issue · 3 comments

If we use the input value property (value={valueFromHook}) the input value changing feedback is delayed since we don't have the value updated yet.

Hello, @aislanmaia
if you use value={valueFromHook} for your input, react will work with such input as controlled component. That meant, you will see the value, that is set to the value directly.

More information about controlled component you can read here https://reactjs.org/docs/forms.html#controlled-components

So, it's better to store 2 values — actual value and debounced value:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { useDebounce } from "use-debounce";

function Input() {
  const [text, setText] = useState("Hello");
  const [debouncedText] = useDebounce(text, 1000);

  return (
    <div>
      <input
        value={text}
        onChange={e => {
          setText(e.target.value);
        }}
      />
      <p>Actual value: {text}</p>
      <p>Debounced value: {debouncedText}</p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Input />, rootElement);

or use uncontrolled component

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { useDebounce } from "use-debounce";

function Input() {
  const [text, setText] = useState("Hello");
  const [debouncedText] = useDebounce(text, 1000);

  return (
    <div>
      <input
        defaultValue={"Hello"}
        onChange={e => {
          setText(e.target.value);
        }}
      />
      <p>Actual value: {text}</p>
      <p>Debounced value: {debouncedText}</p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Input />, rootElement);

Have you tried to change the example for debounced callback? I have tested here in my project and there in the demo.

When you set up value={debouncedValue} your code won't work, as the debounced value will change after the timeout.
So it's expected behavior.

To deal with debouncedValue it's better to store 2 values actualValue (for your input e.g. value={actualValue}) and debouncedValue (for your logic) or use defaultValue.

It's all about the controlled and uncontrolled components in React.