The words Under construction in black text on a yellow background with diagonal black stipes surrounding it
I'm in the process of moving my site. It's still a work in progress. Please excuse the mess and broken links.

Fetching Data From An API With a Button onClick Event Handler In React

TODO: Pull subtitle into page object

TODO: Combine these two posts into one (or eliminate one if they are duplicates)

/fetching-data-from-an-api-with-a-button-onclick-event-handler-in-react-2 /fetching-data-from-an-api-with-a-button-onclick-event-handler-in-react

This is how I'm fetching data from a remote API via a button's onClick event handler in React.

code_start_default_section code_end_default_section

Debugging Stuff

I'm moving stuff around right now. All this below is helping me figure out where to put stuff

        -- title

Fetching Data From An API With a Button onClick Event Handler In React

-- p

TODO: Combine these two posts into one (or eliminate one if they are duplicates)

-- p

/fetching-data-from-an-api-with-a-button-onclick-event-handler-in-react-2
/fetching-data-from-an-api-with-a-button-onclick-event-handler-in-react

-- p

This is how I'm fetching data from a remote API via a button's onClick event handler in React.

-- code/
-- jsx

<!DOCTYPE HTML>
<html>
<head>
    <title>Fetching Remote Data With A Button Click And Error Handling</title>  
    <script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
<style>
body { background-color: #555; }
</style>

</head>
<body>
    <p>Fetching Remote Data With A Button Click</p>
    <p><a href="/">Home</a></p>
    <div id="root"></div>
    <script type="text/babel">
        function App() {
            const [statusMessage, setStatusMessage] = React.useState('TBD')
            const [isFetching, setIsFetching] = React.useState(false)

            React.useEffect(() => {
                if (isFetching) {
                    window.fetch('https://api.weather.gov/')
                        .then(response => response.json())
                        .then(
                            response => {
                                setStatusMessage(response.status)
                            },
                            errorData => {
                                setStatusMessage('ERROR')
                            }
                        )
                    setIsFetching(false)
                }
            })

            return (
                <div>
                    <div>API Status: {statusMessage}</div>
                    <button onClick={() => setFetchStatus('pending')}>Check Status</button>
                </div>
            )
        }

        ReactDOM.render(<App/>, document.getElementById('root'))
    </script>
</body>
</html>

-- /code

-- p

Notes:

-- p

- This example uses `unpkg.com` to call versions of react and babel to make it stand alone, but the script will function in a regular React app.
- In a regular app, you'd use `<script type="text/javascript"></script>` instead of `<script type="text/babel"></script>`.
- The thing that took me the longest to figure out was how to do the trigger itself. I setup a state object that gets updated when the button is pushed which causes a re-render of the component. When that happens, the `useEffect` sees the new state and fires off the fetch. When it's done, it updates the data and returns the state of `pageFetchInProgress` to false. 
- If the component is re-rendered while "pageFetchInProgress" is false, it doesn't pull the page again. 
- While the value is true, it pulls on every re-render. So, if something else causes a re-render while it was fetching, it would fetch again. You could put in another state variable to watch for this and prevent it from happening.

-- p

And here's another example from <<link|NMeuleman|https://twitter.com/NMeuleman) (it's setup in a more traditional way than scalling the script directly so it looks a little different>>. This one doesn't use a true/false switch.

-- code/
-- jsx

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [statusMessage, setStatusMessage] = useState("TBD");

  const fetchData = () => {
    fetch("https://api.weather.gov/")
      .then((response) => response.json())
      .then((response) => {
        setStatusMessage(response.status);
      })
      .catch(() => {
        setStatusMessage("ERROR");
      });
  };
  return (
    <div className="App">
      <div>API Status: {statusMessage}</div>
      <button onClick={fetchData}>Check Status</button>
    </div>
  );
}

-- /code


-- categories
-- React

-- metadata
-- date: 2021-08-15 00:00:00
-- id: 20eokxyk
-- status: published
-- type: post
-- SCRUBBED_NEO: false
-- site: aws