Skip to content

Instantly share code, notes, and snippets.

@fsubal
Last active March 29, 2020 16:36
Show Gist options
  • Save fsubal/b1ab80acb82763c28a3d92ed8f2010af to your computer and use it in GitHub Desktop.
Save fsubal/b1ab80acb82763c28a3d92ed8f2010af to your computer and use it in GitHub Desktop.
Resource class for React Suspence
type Status = "pending" | "success" | "error";
export default class Resource<T> {
static from<T>(promise: Promise<T>) {
return new this(promise);
}
private status: Status;
private result: T;
private suspender: Promise<void>;
private constructor(promise: Promise<T>) {
this.suspender = promise.then(
r => {
this.status = "success";
this.result = r;
},
e => {
this.status = "error";
this.result = e;
}
);
}
read() {
switch (this.status) {
case "pending": {
throw this.suspender;
}
case "error": {
throw this.result;
}
case "success": {
return this.result;
}
default: {
throw new RangeError(
`invariant status: ${JSON.stringify(this.status)}`
);
}
}
}
}
@fsubal
Copy link
Author

fsubal commented Mar 29, 2020

const usersResource = Resource.from(fetchUsers())

const UsersList: React.FC = () => {
  const users = usersResource.read()

  ......
}

@fsubal
Copy link
Author

fsubal commented Mar 29, 2020

🤔

const users$ = Resource.from(fetchUsers())

const UsersList: React.FC = () => {
  const users = users$.read()

  ......
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment