Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
February 10, 2021 04:35 pm GMT

React is a black box. Why does that matter?

Alt Text

React is arguably the most-loved frontend technology. One of the reasons for this success is undoubtedly Reacts small API surface, which has grown in recent years but can still be learned in just a couple of hours.

Even though Reacts API is small, many devs argue that Reacts internals are not only quite complicated, but need to be known these days. So naturally, the question arises does it matter that React is a black box? Does it help us, or does it impact us negatively?

In this article, Ill explore the ins and outs of Reacts abstraction model in pursuit of an answer.

Reacts outside API

In many use cases, Reacts outside API is pretty much nonexistent. If we write JSX like so:

const element = <div>Hello!</div>;
Enter fullscreen mode Exit fullscreen mode

Or like so:

const Component = ({ children }) => (  <>    <p>I am a component</p>    {children}  </>);
Enter fullscreen mode Exit fullscreen mode

Then this is transpiled into a call to jsx from the react/jsx-runtime module. Even before the new JSX transform was introduced, all we had to do was to bring in React, such as:

import * as React from 'react';const element = <div>Hello!</div>;
Enter fullscreen mode Exit fullscreen mode

And a transpiler such as Babel or TypeScript would have transformed it to call React.createElement.

So we can see already that Reacts most important API is pretty much hidden. With createElement or jsx being used implicitly, we never called the outside API explicitly.

Now, excluding more classic APIs such as Component or PureComponent (including their lifecycle), we know that React offers a lot more than we may want (or even need) to use. For instance, using lazy for lazy loading (e.g., for bundle splitting) capabilities is quite cool but requires a Suspense boundary.

On the other hand, we have APIs like useState and useEffect that bring in a certain magic. First, these are all functions, but these functions cannot be used just anywhere. They can only be used inside a component, and only when being called (i.e., rendered) from React. Even then, they may not behave exactly as we expect.

These are APIs that are quite leaky. To understand them, we need to have quite a sophisticated understanding of what happens inside of React which brings us to the inside API.

Reacts inside API

There are three kinds of inside APIs:

  1. APIs that are usually only implemented by a few libraries (such as the reconciliation API more on that later)
  2. APIs that can sometimes be useful and reachable, but not stable, on the outside
  3. APIs that cannot be reached from the outside; they are (and can) only be used internally

I dont want to focus on No. 3 above, as this is anyway beyond our reach. Going for No. 2 does not make much sense either, as these are always subject to change and should be avoided. Which leaves us with APIs that are implemented by only a few libraries but have quite some impact.

As previously mentioned, the most important thing to implement is the reconciliation API. One implementation of this is provided by the render function of react-dom. Another example is renderToString from react-dom/server. Whats the difference?

Lets consider a more complex (yet still simple) component:

const Component = () => {  const [color, setColor] = useState('white');  useLayoutEffect(() => {    document.body.style.backgroundColor = color;  }, [color]);  return (    <>      <p>Select your preferred background color.</p>      <select onChange={e => setColor(e.target.value)} value={color}>        <option value="white">White</option>        <option value="black">Black</option>        <option value="red">Red</option>        <option value="green">Green</option>        <option value="blue">Blue</option>      </select>    </>  );};
Enter fullscreen mode Exit fullscreen mode

There are parts about this component that make it less trivial to use within different rendering options. First, we obviously use the DOM directly, though only in the layout effect. Second, we use an effect and a special one (layout effect), at that.

Using the DOM directly should be avoided as much as possible, but as seen in the example above, we sometimes miss the right methods to do things differently. To improve the situation, we could still guard this line like so:

if (typeof document !== 'undefined') {  document.body.style.backgroundColor = color;}
Enter fullscreen mode Exit fullscreen mode

Or use some alternative check.

That still leaves us with useLayoutEffect. This one is highly rendering-specific and may not exist at all. For instance, using the renderToString function, well get an error when we use this Hook.

One possibility, of course, is to fall back to the standard useEffect. But then we need to know the (not-so-obvious) difference between these two. In any case, the when of the useEffect execution is as foggy as the re-rendering strategy of calling the returned setter from a useState instance.

Lets use this chance to step back a bit and explore why we care about any of this.


Original Link: https://dev.to/wdavidcalsin/react-is-a-black-box-why-does-that-matter-pm

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To