loading...
lessmess

React Renderers: an Overview

ilyalesik profile image Ilya Lesik ・5 min read

React Renderers: an Overview

One of the most advanced features of React is the ability to write renderers for different environments. You can be surprised, but it’s possible to create CLI or Hardware apps using React! In this article, I will look over the most interesting React renderers.

Ink

Ink is a React for CLIs. It allows you to build and test your CLI output using components:

https://dev-to-uploads.s3.amazonaws.com/i/j93bjb1dhhskapybmm0r.gif

The code of the demo:

const Counter = () => {
  const [i, setI] = useState(0);

  useEffect(() => {
    setInterval(() => {
      setI(prev => prev + 1);
    }, 100);
  }, []);

  return <Color>
    {i} tests passed
  </Color>;
}

Ink used by popular libraries such a Gatsby, Parcel, Yarn 2, etc. Also, there are similar libraries such a react-blessed.

React Hardware

React Hardware allows to operate some hardware devices (such as Arduino) through React components:

https://media.giphy.com/media/BeoH46ppAdTPYfpIss/giphy.gif

The code of the demo:

const App = () => {
  const [ledState, setLedState] = useState(false);

  useEffect(() => {
    setInterval(() => {
      setLedState(prev => !prev);
    }, 1000);
  }, []);

  return <Led pin={13} value={ledState ? 255 : 0} />
}
const PORT = 'dev/tty.usbmodem1411';
ReactHardware.render(<App />, PORT);

React Figma

React Figma is a React renderer into Figma. It allows you to use React components as a source for your designs.

https://user-images.githubusercontent.com/1270648/89524327-09365c80-d7ed-11ea-9cb1-08f6fd56a350.gif

React Figma can be useful for describing design systems, creating automations or integrations between some APIs and Figma. E.g. OpenAI and react-jsx-parser allows to create amazing concepts like this. There is sample code written on react-figma:

import * as React from 'react';
import { Page, View, Text } from 'react-figma';

export const App = () => {
    return (
        <Page name="New page" isCurrent>
            <View>
                <View style={{ width: 200, height: 100, backgroundColor: '#dd55aa' }} />
                <Text style={{ color: '#ffffff' }}>text</Text>
            </View>
        </Page>
    );
};

Figma is the most popular design tool for now, but other editors have similar renderers: react-sketchapp for Sketch, react-xd for Adobe XD.

react-three-fiber

react-three-fiber is a React renderer for threejs on the web and react-native.

https://media.giphy.com/media/MwQM6s5nh5L3qbq2Ak/giphy.gif

There is a sample code:

import ReactDOM from 'react-dom'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'

function Box(props) {
  // This reference will give us direct access to the mesh
  const mesh = useRef()

  // Set up state for the hovered and active state
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  // Rotate mesh every frame, this is outside of React without overhead
  useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))

  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={(e) => setActive(!active)}
      onPointerOver={(e) => setHover(true)}
      onPointerOut={(e) => setHover(false)}>
      <boxBufferGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

ReactDOM.render(
  <Canvas>
    <ambientLight />
    <pointLight position={[10, 10, 10]} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>,
  document.getElementById('root')
)

Building dynamic scene graphs declaratively with re-usable components makes dealing with threejs easier and brings order and sanity to your codebase. These components react to state changes, are interactive out of the box, and can tap into React’s infinite ecosystem.

The library has an amazing ecosystem with packages such as react-three-flex - it’s a flexbox implementation, react-xr, react-postprocessing and many others.

react-nil

react-nil is a custom react renderer that renders nothing.

import React, { useState, useEffect } from "react"
import { render } from "react-nil"

function Foo() {
  const [active, set] = useState(false)
  useEffect(() => void setInterval(() => set((a) => !a), 1000), [])
  console.log(active)

  // This is a logical component without a view, it renders nothing,
  // but it has a real lifecycle and is managed by React regardless.
  return null
}

render(<Foo />)

This package allows you to bring Reacts high-level component abstraction to Node, or wherever you need it. Why not manage your REST endpoints like routes on the client, users as components with mount/unmount lifecycles, self-contained separation of concern, and clean side-effects. Suspense for requests, etc.

react-docx

react-docx is a brand new React reconciler for DOCX.js. A sample code:

renderAsyncDocument(
  <section>
    <paragraph heading={Docx.HeadingLevel.HEADING_1}>
      You can pass props as if you are passing them to constructor
    </paragraph>
    <p>There are some helpful shortcuts for often used tags, like this</p>
    <p>
      <t>this one is for TextRun</t>
    </p>
    <p>
      <img
        src="base64 string or buffer object works"
        width={200}
        height={200}
      />
      <href
        src="http://localhost:8080"
        label={"For images and links shortcuts object are provided"}
      />
      This allows for removal of boilerplate for often used objects. In future
      more such object will be implemented.
    </p>
    <Component text="You can use componets of course, just like in react!">
      <t>A child</t>
    </Component>
  </section>
).then((document) => console.log("This is rendered docx document", document));

Also, react-pdf and redocx can be used for equal needs.

Conclusion

Hope you get inspired for creating your own React renderer, it’s possible due to React Reconciler package. I didn’t mention the most popular renderers such as react-dom or react-native, but I tried to collect the most unusual of them. Are you have any additions? Propose them on the comments! 🙌

Thanks

  • Yaroslav Losev @losyear - fact checking, editing

Links

Rendrers:

Renderers writing:

Discussion

pic
Editor guide
Collapse
akhilgautam profile image
Akhil

Jack of all trade