DEV Community

Kenneth Lum
Kenneth Lum

Posted on • Edited on

3 2

The declarative spirits of React Hooks

Suppose the teacher asked you to write a webpage that can show the current time, updated every second, in an exam.

So you wrote

export default function App() {
  const s = useCurrentTime();

  return (
    <div className="App">
      {s}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

So the teacher may say, "wrong, wrong, wrong". It shows something, and it won't update itself.

If it is plain JavaScript, it would be wrong, because things happen imperatively, and the code above does it once only, not updating the time every second.

So you can explain, "I am sorry, this useCurrentTime() is not imperative, but declarative. It is the current time, every second in real time."

How can that be? That's how React is like: it is declarative, but up to a certain point, the programmer needs to make the declarative become true by imperative actions.

The part that bridges between them is:

function useCurrentTime() {
  const [timeString, setTimeString] = useState("");

  useEffect(() => {
    const intervalID = setInterval(() => {
      setTimeString(new Date().toLocaleTimeString());
    }, 100);
    return () => clearInterval(intervalID);
  }, []);

  return timeString;
}
Enter fullscreen mode Exit fullscreen mode

It sets up a repeated action, so that every 100ms, it sets its state to the locale time string. If we don't care about the time off by a bigger fraction of a second, we can use 300, 500, or 667 instead. I don't recommend using 1000 because there can be a case where it was 12:01:02.998, and the 1000ms turns out to be 1016ms due to some delay for the interval event, and then the time would go from 12:01:02 to 12:01:04, assuming the time is by flooring the second.

If that string is the same as before, it won't trigger a re-render of App. When the "state", the string, has changed, then App is re-rendered.

Demo: https://codesandbox.io/s/twilight-waterfall-kbrb0?file=/src/App.js

Dan Abramov wrote about how he'd implement useInterval() as something that is declarative using this methodology.

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more