Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
WIP Suspense and transition
- Fixed bugs - Fixed circular dependencies
- Loading branch information
Showing
28 changed files
with
1,008 additions
and
494 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
export function fetchProfileData() { | ||
const userPromise = fetchUser(); | ||
const postsPromise = fetchPosts(); | ||
const triviaPromise = fetchTrivia(); | ||
return { | ||
user: wrapPromise(userPromise), | ||
posts: wrapPromise(postsPromise), | ||
trivia: wrapPromise(triviaPromise), | ||
}; | ||
} | ||
|
||
// Suspense integrations like Relay implement | ||
// a contract like this to integrate with React. | ||
// Real implementations can be significantly more complex. | ||
// Don't copy-paste this into your project! | ||
function wrapPromise(promise) { | ||
let status = 'pending'; | ||
let result; | ||
const suspender = promise.then( | ||
(r) => { | ||
status = 'success'; | ||
result = r; | ||
}, | ||
(e) => { | ||
status = 'error'; | ||
result = e; | ||
}, | ||
); | ||
return { | ||
read() { | ||
if (status === 'pending') { | ||
throw suspender; | ||
} else if (status === 'error') { | ||
throw result; | ||
} else if (status === 'success') { | ||
return result; | ||
} | ||
}, | ||
}; | ||
} | ||
|
||
function fetchUser() { | ||
console.log('fetch user...'); | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
console.log('fetched user'); | ||
resolve({ | ||
name: 'Ringo Starr', | ||
}); | ||
}, 1000); | ||
}); | ||
} | ||
|
||
const ringoPosts = [ | ||
{ | ||
id: 0, | ||
text: 'I get by with a little help from my friends', | ||
}, | ||
{ | ||
id: 1, | ||
text: "I'd like to be under the sea in an octupus's garden", | ||
}, | ||
{ | ||
id: 2, | ||
text: 'You got that sand all over your feet', | ||
}, | ||
]; | ||
|
||
function fetchPosts() { | ||
const ringoPostsAtTheTime = ringoPosts; | ||
console.log('fetch posts...'); | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
console.log('fetched posts'); | ||
resolve(ringoPostsAtTheTime); | ||
}, 1300); | ||
}); | ||
} | ||
|
||
function fetchTrivia() { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve([ | ||
{ | ||
id: 1, | ||
text: 'The nickname "Ringo" came from his habit of wearing numerous rings.', | ||
}, | ||
{ | ||
id: 2, | ||
text: 'Plays the drums left-handed with a right-handed drum set.', | ||
}, | ||
{ | ||
id: 3, | ||
text: 'Nominated for one Daytime Emmy Award, but did not win', | ||
}, | ||
]); | ||
}, 2400); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import Brahmos, { useState, useTransition, Suspense } from '../src'; | ||
|
||
import { fetchProfileData } from './fakeApi'; | ||
|
||
// const initialResource = fetchProfileData(0); | ||
|
||
export default function App() { | ||
const [tab, setTab] = useState('home'); | ||
|
||
function showProfile(id) { | ||
setTab('profile'); | ||
} | ||
|
||
let page; | ||
if (tab === 'home' || true) { | ||
page = <HomePage showProfile={showProfile} />; | ||
} else if (tab === 'profile') { | ||
page = <ProfilePage />; | ||
} | ||
|
||
// return page; | ||
return <Suspense fallback={<h1>Loading the app...</h1>}>{page}</Suspense>; | ||
} | ||
|
||
function HomePage({ showProfile }) { | ||
return ( | ||
<> | ||
<h1>Home Page</h1> | ||
<Button onClick={showProfile}>Open Profile</Button> | ||
</> | ||
); | ||
} | ||
|
||
function ProfilePage() { | ||
const [resource, setResource] = useState(); | ||
|
||
function showProfile(id) { | ||
setResource(fetchProfileData(id)); | ||
} | ||
|
||
return ( | ||
<> | ||
<Button onClick={showProfile}>Open Profile</Button> | ||
<Suspense fallback={<h2>Loading posts...</h2>}> | ||
{resource && ( | ||
<> | ||
<ProfileDetails resource={resource} /> | ||
|
||
<Suspense fallback={<h2>Loading posts...</h2>}> | ||
<ProfileTimeline resource={resource} /> | ||
<ProfileTrivia resource={resource} /> | ||
<Suspense fallback={<h2>Loading fun facts...</h2>} /> | ||
</Suspense> | ||
</> | ||
)} | ||
</Suspense> | ||
</> | ||
); | ||
} | ||
|
||
function ProfileDetails({ resource }) { | ||
const user = resource.user.read(); | ||
const posts = resource.posts.read(); | ||
return <h1>{user.name}</h1>; | ||
} | ||
|
||
function ProfileTimeline({ resource }) { | ||
const posts = resource.posts.read(); | ||
return ( | ||
<ul> | ||
{posts.map((post) => ( | ||
<li key={post.id}>{post.text}</li> | ||
))} | ||
</ul> | ||
); | ||
} | ||
|
||
function ProfileTrivia({ resource }) { | ||
const trivia = resource.trivia.read(); | ||
return ( | ||
<> | ||
<h2>Fun Facts</h2> | ||
<ul> | ||
{trivia.map((fact) => ( | ||
<li key={fact.id}>{fact.text}</li> | ||
))} | ||
</ul> | ||
</> | ||
); | ||
} | ||
|
||
function Button({ children, onClick }) { | ||
const [startTransition, isPending] = useTransition({ | ||
timeoutMs: 10000, | ||
}); | ||
|
||
function handleClick() { | ||
startTransition(() => { | ||
onClick(); | ||
}); | ||
} | ||
|
||
const spinner = ( | ||
<span | ||
style={{ | ||
marginLeft: 4, | ||
fontSize: 'small', | ||
visibility: isPending ? 'visible' : 'hidden', | ||
}} | ||
> | ||
Loading... | ||
</span> | ||
); | ||
|
||
return ( | ||
<> | ||
<button onClick={handleClick} disabled={isPending}> | ||
{children} | ||
</button> | ||
{isPending ? spinner : null} | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.