“This is the seventh day of my participation in the November Gwen Challenge. Check out the event details: The Last Gwen Challenge 2021

What is React Suspense?

React Suspense is a common way for components to pause rendering while loading data from the cache. Supports the following functions:

  • Allows component trees to be rendered “in the background”
  • When components are fetching data, they are not displayed until the whole tree is ready.

To solve the React Suspense

One barrier to trying React Suspense is the need to “forge” back-end apis to interact with it, or to use public apis with restrictive API keys that add registration steps and security issues.

You can run Netlify Functions locally, essentially setting up a deployable serverless back end next to the local front-end development server. This can be done using serverless Netlify functions at development time, and they work the same way when deployed on Netlify in production. (As an added bonus, check your serverless functionality into the same Git repository as your front end, allowing atomic deployment — which means your endpoints are updated with your clients!)

Pull the warehouse

git clone https://github.com/netlify/create-react-app-lambda.git
cd create-react-app-lambda
yarn
Copy the code

Run yarn start and access localhost:3000. It looks like create-react-appv2, but it has been modified so that if the button is clicked, a request SRC /lambda/hello.js will be made to the specified endpoint. Spend some time getting familiar with SRC /App and SRC /lambda code.

Switch to concurrent mode

Upgrade the React version or install the React cache:

yarn add react-cache
Copy the code
// src/App.js import React, { unstable_ConcurrentMode as ConcurrentMode, // new unstable_Suspense as Suspense, // new Component } from 'react'; / /... // wrap the JSX in line 38-46 in <ConcurrentMode> // ... class App extends Component { render() { return ( <ConcurrentMode> <div className="App"> <header className="App-header">  <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <Suspense maxDuration={1000} fallback={'Loading... '}> <LambdaDemo /> </Suspense> </header> </div> </ConcurrentMode> ); }}Copy the code

As you can see, along with

, you’ve added a

component maxDuration={1000} and a simple backup UI’Loading… ‘to wrap our central
component. All components that use the resource getter must be wrapped in such Suspense components to ensure a fallback UI when pauses and maxDuration go beyond rendering.

Create caches and resources

React – Cache is a new library maintained by the React team as a reference implementation for caches that can be used with React Suspense. The alternative caching will be implemented by the community, including the Facebook Relay and Apollo GraphQL teams.

React-cache itself exposes two low-level apis for very general use cases, so it is generally easier to initialize react Suspense caches as singletons and pass them to resources automatically. Create a new SRC /cache.js file and populate it like this:

// src/cache.js import { createCache, createResource } from 'react-cache'; export let cache; function initCache() { cache = createCache(initCache); } initCache(); export function createFetcher(callback) { const resource = createResource(callback); return { read(... args) { return resource.read(cache, ... args); }}; }Copy the code

Js in SRC/App. We use the 25 lines of code to write a class components processing load state, click, flat /. We netlify/functions provides/hello endpoint, and display the information from the backend:

// currently inside src/App.js
class LambdaDemo extends Component {
  constructor(props) {
    super(props);
    this.state = { loading: false, msg: null };
  }
  handleClick = e => {
    e.preventDefault();
    this.setState({ loading: true });
    fetch('/.netlify/functions/hello')
      .then(response => response.json())
      .then(json => this.setState({ loading: false, msg: json.msg }));
  };
  render() {
    const { loading, msg } = this.state;
    return (
      <p>
        <button onClick={this.handleClick}>
          {loading ? 'Loading...' : 'Call Lambda'}
        </button>
        <br />
        <span>{msg}</span>
      </p>
    );
  }
}
Copy the code

Using the createFetcher utility, we can delete everything and replace it with:

// new code in src/App.js
import { createFetcher } from './cache';
const DataFetcher = createFetcher(() =>
  fetch(`/.netlify/functions/hello`).then(x => x.json())
);
function LambdaDemo() {
  const msg = DataFetcher.read().msg;
  return <p>{msg}</p>;
}
Copy the code

Here you have written your first fetcher, which is a cached resource with a callback function, and we use the browser fetchAPI to return a promise.

When the DataFetcher is read, it suspends the rendering of the LambdaDemo component. When suspended, the fallback text specified in the component is displayed, and when the Promise is resolved, its rendering is complete, and we get the final UI: ‘Loading… ‘“App“fetch“LambdaDemo