Home
Head's Up: I'm in the middle of upgrading my site. Most things are in place, but there are something missing and/or broken including image alt text. Please bear with me while I'm getting things fixed.

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

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.

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>

- This example uses [TODO: Code shorthand span ] 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 [TODO: Code shorthand span ] 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 [TODO: Code shorthand span ] sees the new state and fires off the fetch. When it's done, it updates the data and returns the state of [TODO: Code shorthand span ] 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.

And here's another example from 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.

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>
  );
}