npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@untool/react

v2.1.3

Published

untool react mixin

Downloads

835

Readme

@untool/react

travis npm

@untool/react's main runtime exports are a couple of React components that allow implementers to declaratively control server (or system) behavior. Additionally, @untool/react features full support for react-router's and react-helmet-async's components.

@untool/react provides all three types of @untool/core mixin types. Its core mixin uses @untool/webpack's configureBuild hook to add some settings specific to React, for example support for JSX syntax.

Its runtime, i.e. browser and server, mixins are a bit more interesting as they are untool's only default render mixins. They set up React for client- and server-side rendering. Additionally, they provide mixin hooks of their own to allow you to add your own features, for example Redux support.

During application startup, @untool/react runs a check to determine if certain npm packages are installed multiple times. If you see warnings telling you that this is the case, you will want to make sure you get rid of these duplicates, as they will almost certainly break things in interesting ways.

Installation

$ yarn add @untool/react react react-dom react-router-dom react-helmet-async
# OR npm install @untool/react react react-dom react-router-dom react-helmet

render(element, [options])

render() is @untool/react's main export. You are expected to call it in your applications main entry file and it is essentialy a shorthand: it creates and bootstraps a mixin container and calls its render method.

render accepts two arguments: a react element and an optional options object. @untool/react will use the contents of options.router to configure the React Router instances it controls.

import React from 'react';
import { render } from '@untool/react';
export default render(<h1>hello world</h1>);

The render function serves two main purposes: 'universalifying' or 'isomorphizing' you application, i.e. making sure your app's code can run both on a server and in a browser, and integrating untool's build and runtime environments.

Components

<Miss />

This component allows you to instruct @untool/react to call Express.js' middleware next function. On the client side, it is effectively a no-op.

import { Miss } from '@untool/react';

export default () => <Miss />;

<Status code />

This component enables you to instruct @untool/react to send a different HTTP status code than the default of 200. On the client side, it is effectively a no-op.

import { Status } from '@untool/react';

export default () => <Status code={404} />;

<Header name value />

With this component, you can declaratively set arbitrary HTTP headers from your React application. On the client side, it is effectively a no-op.

import { Header } from '@untool/react';

export default () => <Header name="X-Foo" value="Bar" />;

importComponent(module|moduleLoader, [exportName|exportResolver])

Using the importComponent helper, you can asynchronously require components into your application to help you reduce asset sizes. It works similarly to react-loadable, but is deeply integrated with untool and e.g. supports server-side-rendering.

import { importComponent } from '@untool/react';

const Home = importComponent(
  () => import('./home'),
  ({ Home }) => Home
);

export default () => <Home />;

If you do not specify an exportName or exportResolver, importComponent will fall back to the imported modules default export.

importComponent itself returns a React component supporting some props that enable you to control module loading and (placeholder) rendering.

import { importComponent } from '@untool/react';

const About = importComponent('./about', 'About');

const loader = (load) =>
  Promise.race([
    new Promise((resolve, reject) => setTimeout(reject, 10000)),
    load(),
  ]);

const render = ({ Component, error, loading, ...props }) => {
  return !(error || loading) ? <Component {...props} /> : null;
};

export default () => <About loader={loader} render={render} />;

Components loaded using importComponent (and their dependencies) will be placed in separate chunks, i.e. asset files. @untool/react makes sure that all asset files containing modules used for server-side rendering are referenced in the initial HTML output.

API

render([req, res, next]) (override)

This method is being called whenever you call the main render method. In a server-side, i.e. Node.js, environment it receives the usual arguments any Express middleware receives: req, res, and next. In a client-side, i.e. browser, environment it receives no arguments whatsoever.

const { Mixin } = require('@untool/core');

module.exports = class FooMixin extends Mixin {
  render(req, res, next) {
    if (req) {
      // server
    } else {
      // browser
    }
  }
};

You will not usually have to override this method as it exposes the following mixin hooks to alter its behaviour. In a server-side environment, a fresh mixinable container is being created for every request, including new mixin instances.

bootstrap([req, res]) (parallel)

Within this method, you are expected to set up your application. Your implementation will receive both Express' req and res objects for you to do whatever you like with. If you need to do something asynchronous in this method, just return a Promise.

const { Mixin } = require('@untool/core');

module.exports = class FooMixin extends Mixin {
  bootstrap(req, res) {
    if (req) {
      // server
    } else {
      // browser
    }
  }
};

Remember you can register custom middlewares using @untool/express instead of implementing elaborate request or response handling logic inside your runtime mixin.

enhanceElement(element) (compose)

With this method, you can wrap the React root element with additional components, like Redux' Provider. If you need to do something asynchronous in this method, just return a Promise resolving to the wrapped element.

const { Mixin } = require('@untool/core');

module.exports = class FooMixin extends Mixin {
  enhanceElement(element) {
    return element;
  }
};

fetchData(data, element) (pipe)

Most applications need some sort of data. Implement this method in your mixin, to fetch said data before rendering and return an object with that additional data. If you need to do something asynchronous in this method, just return a Promise resolving to the data.

const { Mixin } = require('@untool/core');

module.exports = class FooMixin extends Mixin {
  fetchData(data, element) {
    return { ...data, foo: 'bar' };
  }
};

getTemplateData(data) (pipe, Server Only)

In case you need to gather additional template data after React rendering, e.g. if you are using styled components, you can add the required data by implementing this hook in your custom mixin. To do so asynchronously, have this method return a Promise resolving to the extended data.

const { Mixin } = require('@untool/core');

module.exports = class FooMixin extends Mixin {
  getTemplateData(data) {
    return { ...data, baz: 'qux' };
  }
};

This hook is only used for server-side rendering, i.e. it will not be called in the browser.