---
type: video
yt_id: VVU2YVRMdUlfajQtMHdpRFN6bWFQY3RRLk1va29vMG1WRUFV
videoId: Mokoo0mVEAU
title: "Fetching and Posting Data in React"
date: "2022-10-03T14:00:11Z"
slug: "fetching-and-posting-data-in-react"
image: 
  name: "fetching-and-posting-data-in-react.jpg"
  alt: "Fetching and Posting Data in React"
  width: 1280
  height: 720
status: 'published'
description: "Learn how to make network requests in a react app to fetch data on load, and post data when users submit a form."
tags: ["axios", "get", "post", "useEffect", "onSubmit", 'nodejs', 'react', 'react js', 'javascript']
---

Learn how to make network requests in a react app to fetch data on load, and post data when users submit a form.

Join this channel to get access to perks:
[https://www.youtube.com/channel/UC6aTLuI_j4-0wiDSzmaPctQ/join](https://www.youtube.com/channel/UC6aTLuI_j4-0wiDSzmaPctQ/join)

This is video #10 in my react series: 

* #9 useEffect Everything You Need To Know: [https://youtu.be/c8R4Cba7PPY](https://youtu.be/c8R4Cba7PPY)

React Proxy | Easiest Fix to CORS Errors: [https://youtu.be/N4yUiQiTvwU](https://youtu.be/N4yUiQiTvwU)

## Chapters:

* 0:00​ Intro
* 1:05 Fetch Data in useEffect
* 4:40 Error State
* 7:37 Loading State
* 9:55 Custom Hook
* 12:26 Suspense
* 13:49 Implementing Search
* 15:23 Race Condition
* 17:05 Abort Controller
* 19:22 Posting Form Data
* 22:44 Sharing State
* 27:54 Summary



## code


**App.jsx**

```jsx
import { useState } from 'react'
import axios from 'axios'
import './App.css'
import { useEffect } from 'react'
import NewJokeForm from './NewJokeForm'


function App() {
  const [jokes, setJokes] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(false)
  const [showForm, setShowForm] = useState(false)

  useEffect(() => {
    const controller = new AbortController()
      ; (async () => {
        let response
        setLoading(true)
        setError(false)

        try {
          response = await axios.get('/api/jokes', {
            signal: controller.signal
          })
          console.log(response)
          setJokes(response.data)
        } catch (e) {
          console.log(e)
          if (axios.isCancel(e)) {
            console.log("aborted")
          } else {
            setError(true)
          }
          return
        } finally {
        }
        
        setLoading(false)
      })()

    return () => {
      console.log("no don't render")
      controller.abort()
    }
  }, [])



  return (
    <div className="App">

      {loading && <div>Loading...</div>}
      {error && <div>Error</div>}

      {jokes.map((joke) => (
        <div key={joke.id}>
          <h3>{joke.text}</h3>
        </div>
      ))}

      {showForm ?
        <>
          <NewJokeForm onNewJoke={joke => setJokes([joke, ...jokes])} />
          <button onClick={() => setShowForm(false)}>Cancel</button>
        </>
        :
        <button onClick={() => setShowForm(true)}>New Joke</button>
      }

    </div>
  )
}

export default App
```

**NewJokeForm.jsx**

```jsx
import { useState } from 'react'
import axios from 'axios'
import { useRef, useEffect } from 'react'

export default function NewJokeForm({onNewJoke}) {
  const [text, setText] = useState('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(false)

  const abortController = useRef(null)

  const abortNetworkRequest = () => {
    console.log("aborting")
    abortController.current?.abort()
  }

  useEffect(() => {
    return abortNetworkRequest
  }, [])

  const handleSubmit = async (e) => {
    abortNetworkRequest()
    abortController.current = new AbortController()
    e.preventDefault()
    setLoading(true)
    setError(false)

    try {
      let result = await axios.post('/api/jokes', { text })
      onNewJoke(result.data)
    } catch (e) {
      setError(true)
    } finally {
      setLoading(false)
    }
  }

  return (
    <>
      {loading ? <div>Loading...</div> :
        <form onSubmit={handleSubmit}>
          <input
            type="text"
            value={text}
            onChange={(e) => setText(e.target.value)}
          />
          <button type="submit">Submit</button>
        </form>
      }
      {error && <div>Error</div>}
    </>
  )
}
```

