Hacker News new | ask | show | jobs
by seanlaff 916 days 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!

1 comments

Is this is what you are looking for? https://vanjs.org/vanui#await
Hmm, 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>
      );
    }
You 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.
Would 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))
      );
    };
Yes. This is how VanJS works. Code with VanJS is often more concise compared to equivalent code with React.
Ah 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/