Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

167
Views
useEffect hook runs infinitely when used in a custom hook

Below is my custom hook, I'm trying to handle everything from the hook. I have seen similar questions but none seems to work for my case and I have been made to believe there's a solution for this approach, jus can't figure it out.

const useResource = (baseUrl) => {
  const [resources, setResources] = useState([]);

  const create = async (resource) => {
    const response = await axios.post(baseUrl, resource)
    setResources(resources.concat(response.data));
    console.log(resources)
    return response.data
  }

  const get = async () => {
    const response = await axios.get(baseUrl);
    setResources(response.data)
    return response.data
  }

  const service = {
    create,
    get
  }

  return [
    resources, service
  ]
}

Here is my approach to use the custom hook, but request keeps looping nonstop, please how do I stop it running after every render?

const App = () => {
  const content = useField('text');
  const name = useField('text');
  const number = useField('text');

  const [notes, noteService] = useResource('http://localhost:3005/notes');
  const [persons, personService] = useResource('http://localhost:3005/persons');
  
  
  useEffect(() => {
    noteService.get();
  }, [noteService])

  useEffect(() => {
    personService.get();
  }, [personService])
  
  const handleNoteSubmit = (event) => {
    event.preventDefault();
    noteService.create({ content: content.value });
  }

  const handlePersonSubmit = (event) => {
    event.preventDefault();
    personService.create({ name: name.value, number: number.value});
  }

Edit: I just had to disable ESLint for the dependency line, because I just need it to run once after every render. Works well!

useEffect(() => {
    noteService.get();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    personService.get();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

As correctly pointed out in comments, each time the component renders and calls your useResource hook, a new service object is created. If this service object is used as a dependency for any other hooks this will trigger their callbacks.

The solution is to memoize the service object so it's being provided as a stable reference. This can be accomplished via the useMemo hook. Because service will be memoized, the create callback will also be memoized and contain stale resources state. To address this update create to use a functional state update when appending new response data to the existing state.

Example:

import { useEffect, useMemo, useState } from 'react';

const useResource = (baseUrl) => {
  const [resources, setResources] = useState([]);

  const create = async (resource) => {
    const response = await axios.post(baseUrl, resource);

    // Functional update to update from previous state
    setResources(resources => resources.concat(response.data));

    return response.data;
  }

  const get = async () => {
    const response = await axios.get(baseUrl);
    setResources(response.data);
    return response.data;
  }

  const service = useMemo(() => ({
    create,
    get
  }), []);

  return [resources, service];
};
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!