React Hooks - refresh some data on page with new data from post

Viewed 67

I have a component that fetches data only when mounted. I ideally only want to make this call once as it is fetching a lot of data. When I make a post request, I receive new data which I want to display on the page and optimistically update the UI. I don't want to refetch the data again as it's an expensive call and would instead just like to update the changed data. I could create an API endpoint that I call to fetch the necessary data on updates but why not update the data with what I receive from the post request?

example code:

const App = () => {
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);
  const [alert, setAlert] = useState(null);
  // data states
  const [user, setUser] = useState(null);
  const [account, setAccount] = useState(null);
  const [key, setKey] = useState(null);
  const [externalAccount, setExternalAccount] = useState(null);
  const [showModal, setShowModal] = useState(false);

  // fetch data upon component mount
  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        // Get data for working with accounts
        const res = await get(
          '/api/v1/account'
        );

        setUser(res.data.user);
        setAccount(res.data.account);
        setKey(res.data.key);
        setExternalAccount(res.data.external_account);
      } catch (e) {
        setError(e);
      }

      setLoading(false);
    };

    fetchData();
  }, []);

  const createAccount = async params => {
    setLoading(true);
    try {
      // send request
      const res = await post(
        '/api/v1/account',
        params
      );

      // set updated account data
      setAccount(res.data.account); //doesn't update on the page. I could call a refetch in the above useEffect but not ideal. Any other options?

      // set success alert
      setAlert('Your account was created successfully.');

      // update loading state
      setLoading(false);
    } catch (e) {
      setAlert(e.message);
      setLoading(false);
    }
  };


  // Define page renders
  if (error) return <ErrorComponent />;
  if (loading) return <Loader />;

  return (
    <>
      <h1>Account</h1>
      {account &&
        <div>
          //display information using state information on user and account
        </div>
      }
      {showModal &&
         <CreateModal 
           toggleModal={setShowModal} 
           createAccount={createAccount} 
           user={user} 
           account={account}
         />
       }
    </>
  );
}

const CreateModal = ({ toggleModal, createAccount }) => {
  const handleSubmit = e => {
    e.preventDetault();
    const params = // set up params for post request
    
    createAccount(params)

  return (
    <form onSubmit={e => handleSubmit(e)}>
      //form code here
    </form>
  )
}
0 Answers
Related