skip to Main Content

I am using ReactJS on the front-end to make a POST request to my Djando API. After I make the POST request, I expect for my React component to update itself without me having to refresh the entire page. I’m using a useEffect hook to call the my endpoint(GET) to retrieve the data I just updated.

import React from 'react'
import CampaignList from '../components/CampaignList'
import {useState, useEffect} from 'react'



const campaignRequest = () => {
  fetch('http://localhost:8000/api/v1/campaigns/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      email_address: "[email protected]",
      first_name: "i",
      last_name: "k",
      stage: "1"
    })
  })
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(error => console.log(error))
}


let Campaigns = () => {
  
  const [recipients, setRecipients] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  console.log("Campaign is re-mounted")
  useEffect(() => {
      setIsLoading(true);
      
      fetch('http://localhost:8000/api/v1/campaigns/')
      .then((res) => res.json())
      .then((data) => {
        setRecipients(data);
        setIsLoading(false);
      })
      .catch(error => console.log(error));
      
      // fetchData()
  }
  ,[]);

  if (isLoading) {
    return <p>Loading...</p>;
  }

  return (
    <div>
      <div>Campaigns</div>
      <CampaignList recipientss={recipients}/>
      {/* <div> 
        {recipients.map((recipient, index) => (
             <h3 key={index}>{recipient.email_address}
             </h3> 
            
          ))}
      </div> */}
      <button onClick={campaignRequest}>Click Me</button>
    </div>
    
  )
}

export default Campaigns

3

Answers


  1. This is because you do not have anything triggering that get fetch to get called again

    put this in your onClick

    () => {
     campaignRequest()
     setLoad(true);
     }
    

    and this in ur useeffect

    if (load) {
       ....
       setLoad(false);
     }
     }, [load])
    
    Login or Signup to reply.
  2. I think this should work. Now recipients are updated every time you click.

    import React from "react";
    import CampaignList from "../components/CampaignList";
    import { useState, useEffect } from "react";
    
    let Campaigns = () => {
        const [recipients, setRecipients] = useState([]);
        const [isLoading, setIsLoading] = useState(true);
    
        const campaignRequest = () => {
            fetch("http://localhost:8000/api/v1/campaigns/", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    email_address: "[email protected]",
                    first_name: "i",
                    last_name: "k",
                    stage: "1",
                }),
            })
                .then((res) => res.json())
                .then((data) => {
                    setRecipients(data);
                })
                .catch((error) => console.log(error));
        };
    
        console.log("Campaign is re-mounted");
        useEffect(() => {
            campaignRequest();
            setIsLoading(false);
        }, []);
    
        if (isLoading) {
            return <p>Loading...</p>;
        }
    
        return (
            <div>
                <div>Campaigns</div>
                <CampaignList recipientss={recipients} />
                <button onClick={campaignRequest}>Click Me</button>
            </div>
        );
    };
    
    export default Campaigns;
    
    
    Login or Signup to reply.
  3. Looks like you want to POST some data to http://localhost:8000/api/v1/campaigns/ when Click Me is clicked and then automatically GET data from the same URL when POST completes.

    In your code snippet a GET request is located inside of a useEffect hook with an empty dependencies array, so it will be executed exactly once – on the initial rended.

    If you want to keep the same code structure, you would have to introduce a new state variable that would trigger the useEffect hook – isAddCampaignLoading for example. You can then move const campaignRequest = () => {...} inside of the Campaigns component and change the isAddCampaignLoading state when campaignRequest succeeds. Finally, you will add isAddCampaignLoading to the dependencies array of your useEffect hook to make it execute every time isAddCampaignLoading changes. I also added a check inside of the hook to make sure campaigns are fetched only when isAddCampaignLoading is false (campaignRequest succeeds).

    import React from 'react'
    import CampaignList from '../components/CampaignList'
    import {
        useState,
        useEffect
    } from 'react'
    
    let Campaigns = () => {
        const [recipients, setRecipients] = useState([]);
        const [isFetchCampaignsLoading, setIsFetchCampaignsLoading] = useState(true);
        const [isAddCampaignLoading, setIsAddCampaignLoading] = useState(false);
    
        const campaignRequest = () => {
            setIsAddCampaignLoading(true)
            fetch('http://localhost:8000/api/v1/campaigns/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    email_address: "[email protected]",
                    first_name: "i",
                    last_name: "k",
                    stage: "1"
                })
            })
                .then(res => res.json())
                .then(data => console.log(data))
                .catch(error => console.log(error))
                .finally(() => setIsAddCampaignLoading(false))
        }
    
        console.log("Campaign is re-mounted")
        useEffect(() => {
            if (!isAddCampaignLoading) {
                setIsFetchCampaignsLoading(true);
                fetch('http://localhost:8000/api/v1/campaigns/')
                    .then((res) => res.json())
                    .then((data) => {
                        setRecipients(data);
                        setIsAddCampaignLoading(false);
                    })
                    .catch(error => console.log(error))
                    .finally(() => setIsFetchCampaignsLoading(false))
            }
        }, [isAddCampaignLoading]);
    
        if (isFetchCampaignsLoading) {
            return <p> Loading... </p>;
        }
    
        return ( <div>
                <div> Campaigns </div> 
                <CampaignList recipients={recipients}/> 
                {
                /* <div> 
                            {recipients.map((recipient, index) => (
                                 <h3 key={index}> 
                                    {recipient.email_address}
                                 </h3> 
                              ))}
                          </div> */
            } 
               <button onClick={campaignRequest}>Click Me</button> 
               </div>
        )
    }
    
    export default Campaigns
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search