Skip to content

dat2/react-suspense-saga

Repository files navigation

Overview

A React component that renders the results of an ES2015 generator.

The suspense is killing me, so I decided to explore this before React implements it themselves!

Getting started

Install

npm i react-suspense-saga

or

yarn add react-suspense-saga

Quick Example

import runner from 'react-suspense-saga'
import { call, render } from 'react-suspense-saga/lib/effects'

import Api from './Api'

function* greeter() {
  yield render(
    <p>Loading...</p>
  )
  try {
    const user = yield call(Api.fetchUser)
    yield render(
      <p>
        Hello {user.name}!
      </p>
    )
  } catch(e) {
    yield render(
      <p>
        Oh no, something failed!
      </p>
    )
  }
}

export default runner(greeter)

Examples

API Documentation

Call

call(
  func: (...args: Array<any>) => Promise<any>,
  ...args: Array<any>
): Effect

This will instruct the runner to return the results of the promise back to the generator when it resolves or rejects.

eg.

const AsyncGreeting = runner(function*() {
  yield render(<p>Loading...</p>)
  try {
    const response = yield call(fetch, '/api/user')
    const user = yield call(() => response.json())
    yield render(<p>Hello { user.name }!</p>)
  } catch(e) {
    yield render(<p>Something went wrong 🤔</p>)
  }
})

delay

delay(
  ms: number
): Effect

This will instruct the runner to use setTimeout.

eg.

const MyComponent = runner(function*() {
  yield delay(1000)
  yield render(<p>my component</p>)
})

render

render(
  node: React.Node | React.Component,
  extraProps: Object?
): Effect

This will render a node or a react component.

eg.

const Loading = () => <p>Loading...</p>

const MyComponent = runner(function*() {
  yield render(Loading) // props for MyComponent will get forwarded to this
  yield render(<p>my component</p>)
  yield render(MyOtherComponent, { name: 'nick' })
})

takeProps

takeProps(): Effect

This will hook into the componentWillReceiveProps lifecycle method, and block your saga until the props have changed. It will also receive the initial props on componentDidMount.

eg.

const GreetingWithProps = runner(function*() {
  // Every time the props change, we will re-render
  while (true) {
    const { loading, name } = yield takeProps()
    if (loading) {
      yield render(<p>Loading...</p>)
    } else {
      yield render(<p>Hello {name}</p>)
    }
  }
})

About

redux-saga + react, experimental

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published