Skip to content

Instantly share code, notes, and snippets.

@tsingson
Forked from anthowave/valtio-promise.js
Created March 27, 2022 23:15
Show Gist options
  • Save tsingson/d78e9647cb8aa69d23c4d93480b42792 to your computer and use it in GitHub Desktop.
Save tsingson/d78e9647cb8aa69d23c4d93480b42792 to your computer and use it in GitHub Desktop.
Valtio(proxy-based state management library) demo that natively handles promise with React suspense
import React, { Suspense } from "react";
import { proxy, useProxy } from "valtio";
import { a, useSpring } from "@react-spring/web";
const fetchData = async (id) => {
const response = await fetch(
`https://hacker-news.firebaseio.com/v0/item/${id}.json`
);
return await response.json();
};
const state = proxy({
postId: 9001,
postData: fetchData(9001),
setPostId: (next) => {
state.postId = typeof next === "function" ? next(state.postId) : next;
state.postData = fetchData(state.postId);
}
});
function Id() {
const { postId: id } = useProxy(state);
const props = useSpring({ from: { id: 0 }, id, reset: true });
return <a.h1>{props.id.to(Math.round)}</a.h1>;
}
function Next() {
const { setPostId } = useProxy(state);
return (
<button onClick={() => setPostId((x) => x + 1)}>
<div>→</div>
</button>
);
}
function PostTitle() {
const {
postData: { by, title, url, text, time }
} = useProxy(state);
return (
<>
<h2>{by}</h2>
<h6>{new Date(time * 1000).toLocaleDateString("en-US")}</h6>
{title && <h4>{title}</h4>}
<a href={url}>{url}</a>
<p>{text}</p>
</>
);
}
export default function App() {
return (
<>
<Id />
<div>
<Suspense fallback={<h2>Loading...</h2>}>
<PostTitle />
</Suspense>
</div>
<Next />
</>
);
}
// Codesandbox demo: https://codesandbox.io/s/valtio-async-demo-r4y2l?file=/src/App.js
// Credit goes to DaiShi, creator of valtio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment