Hacker News new | ask | show | jobs
by chrisdalke 2017 days ago
One other common use for useRef that isn't mentioned here is to bridge your React component with a JS library outside the React ecosystem.

For example, if you wanted to instantiate a charting library like uPlot (https://github.com/leeoniya/uPlot) you might instantiate a uPlot object storing state and methods for the chart. You can perform the chart initialization in a useEffect hook, and use a ref to keep a reference to the instance you've created.

1 comments

Very important use case. Actually, I am baffled how a lot of the common frameworks (React, Angular) omit some kind of documentation on how to integrate with third-party libraries that operate on the DOM directly (charting being a very good example) or how do something imperatively with the DOM (e.g. scroll to element after the user did something). In React I actually know how to do it properly, in Angular, however, I am completely lost how to do it.
Indeed, no hooks mentioned on that page, though. Also, on first glance, that looks like trivial integrations.

Ah, I also forgot to mention, what I'd like to see is more documentation on how to hide an imperative API behind a more declarative React/Angular etc. API. That's not always trivial but often what you want.

I think it's especially important because while you often can find ready-made wrapper for popular pure JS libraries they are usually abandoned (and thus don't keep up with the latest versions) or have some flaw that bites you sooner or later. My current recommendation is to write your own wrapper unless the wrapper is an official one of the authors of the underlying JS library. Naturally, that's not always feasible for complex libraries, but matter of fact you don't always need the full functionality of that library so you only have to wrap what you need.

I completely agree -- I've been bitten a few times using React wrappers that turn out to have subtle flaws or are unmaintained. Generally I just write my own wrapper with some clunky combination of hooks to manage the lifecycle of data.

One common pattern I end up using for a lot of imperative calls is a "useAsyncFunction" hook which runs any async function, returns state for loading, error, and the result of that function.

Unfortunately each library handles DOM manipulation, configuration options, callbacks, instantiation, etc. in its own way, and so I don't think there's any generalized solution.