4 ms·
This is cool, though I think a table-stakes example that is missing is how to do a network request. I see the stargazers example but that entire component is aw
by seanlaff 3y ago
This is cool, though I think a table-stakes example that is missing is how to do a network request. I see the stargazers example but that entire component is awaited, which doesn't mirror the common case of async fetch in response to user input, in which the response is fed to sub-components.
The stargazer example leaves me with questions like- are components both async and non-async? What if the component re-renders due to other state changes, is my network request fired more than once? Do I have a "component coloring" problem where once one subcomponent is async, the entire parent hierarchy has to be?
Im sure there's answers to these questions if I read the docs, but as a curious passer-byer an example mirroring this common ui pattern would answer a lot of questions for me!
- taoxin 3y agoIs this is what you are looking for? https://vanjs.org/vanui#await https://vanjs.org/vanui#await
- seanlaff 3y agoHmm, maybe! Is that the idiomatic way to do async? I was thinking something along the lines of this, which react devs will have written a variation of plenty of times :) import { useEffect, useState } from "react"; const GithubUser = ({ login, avatar_url, html_url }) => ( <div> <img src={avatar_url} style={{width:40, height:40}}/> <a href={html_url}>{login}</a> </div> ); export function App() { const [stargazerResp, setStargazerResp] = useState([]); const [repo, setRepo] = useState("vanjs-org/van"); useEffect(() => { fetch(`https://api.github.com/repos/${repo}/stargazers?per_page=5`) .then((r) => r.json()) .then((r) => Array.isArray(r) ? setStargazerResp(r) : setStargazerResp([])); }, [repo]); return ( <div className="App"> <input value={repo} onChange={(e) => setRepo(e.target.value)} /> <ul> {stargazerResp.map((s) => ( <li key={s.login}> <GithubUser login={s.login} avatar_url={s.avatar_url} html_url={s.html_url} /> </li> ))} </ul> </div> ); }
- taoxin 3y agoYou can do with VanJS in this way as well. `set...` functions in React map to `....val = ...` in VanJS (which I think is more intuitive). But the `Await` component is a good abstraction so that you can specify what to show when the resources are being fetched and what to show when there are errors while fetching the resources.
- seanlaff 3y agoWould we expect the list to re-render once the fetch finishes? This may just be years of react poisoning my brain const Stargazers = () => { const stargazers = van.state([]); fetch(`https://api.github.com/repos/vanjs-org/van/stargazers?per_page=5`) .then((r) => r.json()) .then((r) => stargazers.val = r); return ul( stargazers.val.map((s) => li(s.login)) ); };
- taoxin 3y agoYes. This is how VanJS works. Code with VanJS is often more concise compared to equivalent code with React.
- seanlaff 3y agoAh ok! Very cool. Maybe I'm still missing a tiny piece of syntax? I don't see any output when I run that code in the fiddle https://jsfiddle.net/397fb684/ https://jsfiddle.net/397fb684/
- taoxin 3y agoAh.. you need a binding function to wrap the state-derived content into a reactive UI element, see: https://vanjs.org/tutorial#state-derived-child https://vanjs.org/tutorial#state-derived-child. I made the change in your code to make it work: https://jsfiddle.net/rkfmpx06/1/ https://jsfiddle.net/rkfmpx06/1/