Skip to content

Instantly share code, notes, and snippets.

@lamtranweb
Created May 25, 2019 06:50
Show Gist options
  • Save lamtranweb/593df9a4e1d162143cfce24ed5f068b1 to your computer and use it in GitHub Desktop.
Save lamtranweb/593df9a4e1d162143cfce24ed5f068b1 to your computer and use it in GitHub Desktop.

Revisions

  1. lamtranweb created this gist May 25, 2019.
    63 changes: 63 additions & 0 deletions fetch-with-URL-check.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    import * as React from "react";
    import { useState, useEffect, ReactNode } from "react";
    import { render } from "react-dom";

    import "./styles.css";

    const URL = "https://jsonplaceholder.typicode.com/todos/1";

    interface Todo {
    id: number;
    userId: number;
    title: string;
    completed: boolean;
    }

    interface Props {
    url: string;
    }

    const isValidUrl = (url: string) =>
    url && url.startsWith("https://jsonplaceholder.typicode.com");

    function App<Props>({ url }) {
    if (!isValidUrl(url)) {
    return <h1> Invalid URL {url}</h1>;
    }

    const [loading, setLoading] = useState<boolean>(false);
    const [error, setError] = useState<TypeError>(undefined);
    const [state, setState] = useState<Todo>(undefined);

    useEffect(() => {
    (async () => {
    setLoading(true);
    try {
    const response = await fetch(url);
    const json = await response.json();
    setState(json);
    } catch (e) {
    setError(e);
    } finally {
    setLoading(false);
    }
    })();
    }, [setError, setLoading, setState]);

    let State: ReactNode = null;

    if (loading) {
    State = <h1>Loading</h1>;
    }
    if (error) {
    State = <h1>{error.message}</h1>;
    }
    if (state) {
    State = <h1>{state.title}</h1>;
    }

    return <div className="App">{State}</div>;
    }

    const rootElement = document.getElementById("root");
    render(<App url={URL} />, rootElement);