DEV Community

hyper
hyper

Posted on • Originally published at Medium on

1

React: The great Abstraction

React + JSX was launched at JSConf in 2013, I was one of the fortunate Javascript developers to attend the conference, and I will say the reaction and response on the initial announcement was pessimistic at best. The JS nation revolted against this XML like syntax in their JS for like 6 months, then the rest is history. React has grown into the most popular front-end library in the community.

React the planet! 🌎

Hack the planet was the nerd rallying cry in the movie Hackers 1995

Over the last 8 years, we have seen React implemented in just about every presentation layer you can think of, mobile, tvs, terminal, etc. We have also seen React implement music, animations, and more. React creates a declarative composable model on top of Javascript.

Why not servers? 🖥️

There is a project called React-Nil, this project simply lets you create react components that return null. What? What good does that do? Well, this allows developers to use React on the server.

Mad Science 🧬

Disclaimer: I have no idea if this is a good idea or not, but lets have some fun! 🤓

What if we could use React to express our server API?

render(
  <App>
    <Request path="/" handler={hello} />
    <Listen port={3000} />
  </App>
)
Enter fullscreen mode Exit fullscreen mode

Why not? 🤷

With React-Nil we can!

In this demo we are using Deno 1.8 with Opine web framework

create new folder called :hyper-sauce

mkdir hyper-sauce
cd hyper-saurce
touch hyper.js
touch mod.jsx
touch import_map.json
Enter fullscreen mode Exit fullscreen mode

setup our dependencies in import_map.json

{
  "imports": {
    "react": "https://cdn.skypack.dev/react?dts",
    "react-nil": "https://cdn.skypack.dev/react-nil?dts",
    "opine": "https://deno.land/x/opine@1.1.0/mod.ts"
  }
}
Enter fullscreen mode Exit fullscreen mode

modify hyper.js with our server components

import React from 'react'
import opine from 'opine'

export function Listen({app, port}) {
  app.listen(port)
  console.log('server listening on port ', port)
  return null
}

export function Request({app, method='get', path="/", handler}) { 
  app[method](path, handler)
  return null
}
Enter fullscreen mode Exit fullscreen mode

pretty cool, we are writing react functional components

export function App(props) {
  const app = opine()
  return React.Children.map(props.children, child => {
    if (React.isValidElement(child)) {
      return React.cloneElement(child, { app })
    }
    return child
  })
}
Enter fullscreen mode Exit fullscreen mode

save hyper.js

mod.jsx

NOTE: Deno automatically handles JSX or TSX, just name your file with .jsx or .tsx extension. ✨

import React from 'react'
import { render } from 'react-nil'
import { App, Request, Listen } from './hyper.js'

render(
  <App>
    <Request path="/" handler={hello} />
    <Listen port={3000} />
  </App>
)

function hello(req, res) {
  res.send('Hello from React on the Server!')
}
Enter fullscreen mode Exit fullscreen mode

Let’s run it!

deno run --allow-read --allow-net --import-map=./import_map.json mod.js
Enter fullscreen mode Exit fullscreen mode

Open up a browser and navigate to http://localhost:3000

You should see ‘Hello World’!

One step further

How about we take this a step further, and instead of passing a handler function, lets use a child component.

render(
  <App>
    <Request path="/">
      <Show />
    </Request>
    <Request path="/_add" method="POST">
      <Inc />
    </Request>
    <Request path="/_sub" method="POST">
      <Dec />
    </Request>
  </App>
)
Enter fullscreen mode Exit fullscreen mode

We can modify the Request component to pass a handler function to the child components.

export function Request({app, method="get", path="/", children}) {
  return React.Children.map(children, 
    child => {
      if (React.isValidElement(child)) {
        return React.cloneElement(child, { 
          handler: fn => app[method](path, fn)
        })
      }
      return child
    })
}
Enter fullscreen mode Exit fullscreen mode

Then we can implement our handlers using components:

function Hello({handler}) {
  handler((req, res) => res.send('Hello!'))
  return null
}
Enter fullscreen mode Exit fullscreen mode

You can run the full demo at https://github.com/hyper63/react-server-demo.git

Summary

React is a powerful abstraction, with context, hooks, suspense, and so much more, it could possibly be useful on the server, with the React-Nil library we can experiment and push the boundaries and see what shakes out!

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)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs