React: "I really wish this is how I could write components."

joelnet profile image JavaScript Joel ・1 min read

Challenge Accepted!

code for useMatchFetch down below.

import React from "react";
import { useMatchFetch } from "./effects/useMatchFetch";

export const Example = () => {
  const render = useMatchFetch("https://swapi.co/api/people/1/?format=json");

  return render({
    pending: () => <div>Loading</div>,
    error: err => <div>{err.toString()}</div>,
    data: data => <pre>{JSON.stringify(data, null, 2)}</pre>

Watch my Live Stream

Want to see my process on how I created this? Watch me on Twitch!

Twitch Screenshot


I actually really like this. I think I might end up using this in a few places.

import { useState, useEffect } from "react";

const render = data => match =>
  data.pending ? match.pending()
  : data.error ? match.error(data.error)
  : data.data  ? match.data(data.data)
  : null // prettier-ignore

export const useMatchFetch = url => {
  const [data, setData] = useState({ pending: true });

  useEffect(() => {
      .then(response => response.json())
      .then(data => setData({ data, pending: false }))
      .catch(error => setData({ error, pending: false }));
  }, [url]);

  return render(data);


Follow me on Twitter @joelnet


Posted on by:

joelnet profile

JavaScript Joel


Cofounded Host Collective (DiscountASP.net). Cofounded Player Axis (Social Gaming). Computer Scientist and Technology Evangelist with 20+ years of experience with JavaScript!


Editor guide

I really think this is such a cool DEV use-case: Taking a tweet and expanding on, replying to and generally going deeper on the idea.

I also think a browser extension which could add a button like this to Twitter would be kind of awesome if anyone wants to build that 😄

We actually have an existing Twitter extension we haven't touched in a while but would definitely welcome this added functionality if anyone wants to make a PR (along with some other needed updates 😬)

GitHub logo thepracticaldev / DevTwitter

Bringing dev.to headlines to your Twitter browsing experience.

DevTwitter Chrome Extension

Bringing dev.to headlines to your Twitter browsing experience.

Alt text


Go to The Chrome Store to download the extension.

To access development releases, simply download or clone this code and load as an unpacked extension.

Unpacked Extension

  • If you downloaded the code, unzip the file.
  • Open (chrome://extensions/) or select hamburger menu > More Tools > Extensions in the menu.
  • Enable the developer mode at top right.
  • Click Load unpacked extension... and select the chrome-extension folder.


  • Display dev.to links on the sidebar of the Twitter desktop browser under other trends, bringing a bit more dev life into your Twitter browsing experience. Simple, eh?

Future features

Twitter is a great way to connect and collaborate with other developers, and it would be fun to build in features that did that. The dev.to team will be thinking of ways to do this, but contributions are super welcome.

It is important…

Anyway, sorry to go on a tangent, this just made me happy. 🙂


I really think this is such a cool DEV use-case: Taking a tweet and expanding on, replying to and generally going deeper on the idea.

I like this too. If someone has created a tweet, there's already some interest in that subject. I liked this tweet in particular because I kept thinking about it a few hours later.

Better integration would be awesome!


Heh, I've done that a couple of times, about git and about starting Node projects. I like the spark that a tweet can form in your mind and send you down a rabbit hole following ideas and writing code and posts in response.


The fastest way to get me to do something is to tell me it can't be done!


I, too, want pattern matching in javascript and i also want Maybes and Eithers.


Same. You can use Maybes and Eithers today with a package import. The barrier is getting people familiar with them. Right now there's a lot of push back against them just because of familiarity bias.

If the language adopted them as native though, people would jump on board.

People are silly like that.


If the language adopted them as native though, people would jump on board.

I think so too. Rust has them, they are called Option and Result. I secretly want Rust to become more popular so people can learn about them and how useful they are, and also start using them in other languages (and by other i mean javascript)

Interestingly, Rust has started to become more popular in Web Land as a language for writing WASM modules, in part because of the strong support from the Rust team themselves. See developer.mozilla.org/en-US/docs/W...


I like this one dev.to/_gdelgado/type-safe-error-h...
Currently im working on trying to reduce all the friction that happens when a language doesn’t support it more natively, hopefully have a post up with samples in the next month or so :)


Z looks interesting for sure. It's a little limited though. But it would work fine for this use case.


Glorious! I love the idea.

I'm not a super big fan of hooks, I still prefer HOC, so for those who are interested, here is a similar alternative I am testing out.

Alternatively, a HOC would work just as well, and be decoupled.

// untested
import { ComponentType, useEffect, useState } from 'react'
import defaultPending from './defaultPending'
import defaultError from './defaultError'
import curry from 'lodash/curry'

interface IWithDataOptions<T> {
    pending?: () => ComponentType,
    error?: (e: Error) => ComponentType,
    data: (d: T) => componentType
export const withData = curry(<T> (
    url: string,
    options: IWithDataOptions<T> | ComponentType
) => {
    const error = options.error || defaultError
    const pending = options.pending || defaultPending
    const dataRender = options.data || options
    const WithData = (props) => {
        const [data, setData] = useState({ pending: true });

        useEffect(() => {
                .then(response => response.json())
                .then(data => setData({ data, pending: false }))
                .catch(error => setData({ error, pending: false }));
        }, [url]);
        if(data.pending) return pending()
        if(data.error) return error(data.error)
        return dataRender(data.data)
    return WithData

// example 1
const Example = withData("https://swapi.co/api/people/1/?format=json", {
    pending: () => <div>Loading</div>,
    error: err => <div>{err.toString()}</div>,
    data: data => <pre>{JSON.stringify(data, null, 2)}</pre>
<Example />

// example 2
const Example = withData("https://swapi.co/api/people/1/?format=json", (data) => <pre>{JSON.stringify(data, null, 2)}</pre>);
<Example />

// example 3
const withExampleData = withData("https://swapi.co/api/people/1/?format=json")
const Example =  withExampleData((data) => <pre>{JSON.stringify(data, null, 2)}</pre>)
<Example />

const CustomLoaderExample = withExampleData({
    peding: () => <div>Just a second...</div>,
    data: (data) => <pre>{JSON.stringify(data, null, 2)}</pre>

<CustomLoaderExample />


HOCs are another great way to solve this. Great examples!


I think it would be nice to have a refetch action so that the request can be remade even to the same url.
Also I think it would be nice to be able to distinguish then between the initial fetch, and future updates.

Also im debating with myself if I like the separate callbacks for each case, or if I would prefer being given the loading, data and error props together, and then do a more imperative approach with conditions. It seems more flexible.
In that case I would make the render function separately available, instead of wrapping it around the data

Something along the lines of the react-apollo graphql HOC and Query component etc, but then for REST.


All great features! Submit a pull request ;)


Anyway, here it is; written in the train, so apologies for any typos ;-)



Would love to, but where to? Where the codes at? :)
(Maybe im blind)

There's no repo for it. It was just a live stream demo :)


Nice write up! :)

Reminds me of these posts using daggy from fantasy-land

nice little library that wraps it up


One of the reasons, I decided not to make this an npm package. I figured something was already out there. I thought it would be fun to show the process.

Looks like those other libs have the same idea. I always love seeing an article with daggy!

daggy is actually a perfect use case for this.




Yeah indeed a lot times there’s a solution but not a how to reach it write up or something like that so def keep coming with the process writes up for sure !! :)

That was one thing I found interesting about this process. Most of the time the ideal solution would be created ahead of time and then you would teach that process.

But it's interesting to see how you would think to get to that conclusion on your own.

I think that's the difference between live streams and tutorials. You get to see the thought process, which I really enjoy watching!



But it's interesting to see how you would think to get to that conclusion on your own.

yah that process is fun, we used to do FP lunch sessions at an old job and refactor some current/legacy code into something we just learned or found interesting right on a big screen tv so everyone could watch and we talk thru the process.


Haha, I wrote the same thing and it was so quick that I didn't bother to post it.

I seldomly use any libraries in React, because it's so easy and quick to build them yourself. Just a hand full of small util compnents and you're good to go.


Agreed. Plus the problem with libraries is they have to cover the use cases of every application in the works. Most times your one liner function is enough for your use case.



I couldn't write an equivalent to React-Router or Native-Navigation, but I don't have to. A 10line component covers the use-cases I have.


I ran into a few different packages that did something very similar. This is the reason I didn't create an npm package. I think there are enough already.

But I thought the process would be fun, which is why I lived streamed it.

Hopefully people enjoy the process that went into making it happen.




I hope it was fun! Sorry if my comment implied I didn't see value in this, I totally do. I dig seeing the thought process behind the code in addition to the code itself. Have a good one!

No your comment didn't imply that it wasn't fun. I got you ;)

You too!


Very functional and very Elm'ish.

I've watched this talk and it covered exactly that.


Thanks for the tip! I'm saving this video to my Watch Later.


Definitely worth watching. You might find some inspiration on how to improve your React code even more :)

There's always room for improvement!


Your code is subject to race conditions.

See dev.to/sebastienlorber/handling-ap...

You'd rather use a lib that solves it for you with all the edge cases, like github.com/slorber/react-async-hook


Yep this is correct! Any previous fetch needs to be aborted.

Since this code was just for fun, I don't think I'll be spending the time to add these cases into it. But if someone wants to contribute a gist, i'll gladly link it.



I'd probably use ReasonReact for this :D


ReactReason is a very interesting project. It's hard to convince large companies to switch to a totally different language though.

I'm still looking forward to playing with ReasonML for some personal projects.


What if you want to render a loader while new data is loading? That means you'd render a loader + the current data at the same time. Same with errors.


Submit a pull request ;)


Scala-js allows writing react components this way


This sounds pretty cool. I haven't seen scalajs but if it has pattern matching I'm down!


First time that I "unicorned" article! Well played Sir!


I'm so honored 😁