Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a more relevant react example using react-query #270

Open
kasperpeulen opened this issue Jul 10, 2022 · 4 comments
Open

Add a more relevant react example using react-query #270

kasperpeulen opened this issue Jul 10, 2022 · 4 comments

Comments

@kasperpeulen
Copy link

Would be nice to add a more up to date react example, maybe something like this:

export function Todos() {
  const todos = useTodosQuery();
  return (
    <div>
      {match (todos) {
        when ({ status: 'loading' }): "Loading..."
        when ({ status: 'error', error }): <span>Error: {error.status}</span>
        when ({ status: 'success', data, isFetching }): (          
          <>
            <div>
              {data.map((todo) => (
                <p key={todo.id}>{todo.title}</p>
              ))}
            </div>
            <div>{isFetching ? "Background Updating..." : " "}</div>
          </>
        )
      }}
    </div>
  );
}

Btw, what would happen here if the match is not exhausted? It would be awesome if TS could warn about that.

This is using react-query v4 beta:
https://codesandbox.io/s/kind-butterfly-rh2vvl?file=/src/App.tsx

import { useQuery } from "react-query";

export function App() {
  const todos = useQuery<{ title: string; id: string }[], Response>(
    ["todos"],
    async () => {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/todos"
      );
      if (!response.ok) throw response;
      return response.json();
    }
  );

  return (
    <div>
      <h1>Todos</h1>
      {/* Match expression */}
      <div>
        {match (todos) {
          when ({ status: 'loading' }): "Loading..."
          when ({ status: 'error', error }): <span>Error: {error.status}</span>
          when ({ status: 'success', data, isFetching }): (          
            <>
              <div>
                {data.map((todo) => (
                  <p key={todo.id}>{todo.title}</p>
                ))}
              </div>
              <div>{isFetching ? "Background Updating..." : " "}</div>
            </>
          )
        }}
      </div>
      {/* Ternaries */}
      <div>
        {todos.status === "loading" ? (
          "Loading..."
        ) : todos.status === "error" ? (
          <span>Error: {todos.error.status}</span>
        ) : (
          <>
            <div>
              {todos.data.map((todo) => (
                <p key={todo.id}>{todo.title}</p>
              ))}
            </div>
            <div>{todos.isFetching ? "Background Updating..." : " "}</div>
          </>
        )}
      </div>
    </div>
  );
}
@ljharb
Copy link
Member

ljharb commented Jul 10, 2022

@kasperpeulen a match, by default, throws an exception when the default: is hit, so TS should be able to warn about it.

What about your examples is more up to date than the ones in the readme?

@aspirisen
Copy link

I think it is worth to update the example, currently the example uses render function approach and from first glance it is not clear that you can use match directly in JSX

@rawpixel-vincent
Copy link

rawpixel-vincent commented Jul 29, 2023

code alternative not using this proposal should also be added for comparison

export function Todos() {
  const todos = useTodosQuery();
  if (todos.status === 'loading') {
    return <div>Loading</div>;
  }
  if (todos.status === 'error') {
    return <span>Error: {todos.error.status}</span>;
  }

  return (
    <div>
      <div>
        {todos.map((todo) => (
          <p key={todo.id}>{todo.title}</p>
        ))}
      </div>
      <div>{isFetching ? 'Background Updating...' : ' '}</div>
    </div>
  );
}
const STATES = {
  loading: (todos) => <div>Loading</div>,
  error: (todos) => <span>Error: {todos.error.status}</span>,
};

export function Todos() {
  const todos = useTodosQuery();

  return (
    STATES[todos.state]?.(todos) || (
      <div>
        <div>
          {todos.map((todo) => (
            <p key={todo.id}>{todo.title}</p>
          ))}
        </div>
        <div>{isFetching ? 'Background Updating...' : ' '}</div>
      </div>
    )
  );
}

@LivioGama
Copy link

LivioGama commented Sep 27, 2023

I stumbled upon this randomly after developing this a few weeks ago 😂 https://github.com/LivioGama/use-query-state-layout
Because I was pissed of my sin 😂 #300

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants