1

I try to call a method in service class from MainPanel with useEffect hook:

Here is my MainPannel:

function MainPanel() {

  const [customers, setCustomers] = useState([]);
  

  useEffect(() => {
    const getCustomers = async () => {
      const customers = await getCustomerList();
      setCustomers({ customers });
      console.log(customers)
    };
    getCustomers()
  }, []);

  return (
    <div className="App">
      {/* do something */}

    </div>
  );
}

export default MainPanel;

And here is the service method that I called from useEffect:

export async function getCustomerList() {

    axios.get("http://localhost:8080/customer", { params: { id: 1 } })
    .then(response => console.log(response.data))
}

In this scenario useEffect is working but working twice and console.log is printing twice (2 times log correct value and 2 times undefined).

If I just get the data with return statement instead of printing to console like

export async function getCustomerList() {

    axios.get("http://localhost:8080/customer", { params: { id: 1 } })
    .then(response => {return response.data})
}

Same thing happening but this time response is coming as undefined. I know they are separate problems but I just need to understand a proper way of fetching data and use it in useEffect only once.

How can I achieve it ?

Chris Garsonn
  • 717
  • 2
  • 18
  • 32
  • 1
    are you using `` in your app.js or index.js? – miyav miyav Apr 13 '22 at 21:53
  • what does `getCustomers()` do? – miyav miyav Apr 13 '22 at 21:55
  • @miyavmiyav it is in index.js and between it there is – Chris Garsonn Apr 13 '22 at 21:58
  • 2
    the strict mode renders components two times if its in production build or you remove it it will trigger useEffect only once – miyav miyav Apr 13 '22 at 21:58
  • @miyavmiyav for now it is doing nothing but what I want to do is just call function and get data at beginning and initialize to a variable and then use it as a datasource – Chris Garsonn Apr 13 '22 at 21:59
  • 1
    @miyavmiyav `React.StrictMode` only works in non-production builds. See the note at the ***top*** of the [page](https://reactjs.org/docs/strict-mode.html). "Note: Strict mode checks are run in development mode only; they do not impact the production build." – Drew Reese Apr 13 '22 at 22:02
  • 1
    @DrewReese thats why I said in production OR if you disable it it will fire only once – miyav miyav Apr 13 '22 at 22:03
  • @miyavmiyav Oh, I see, grammar fail. I read that comment as "the strict mode renders components two times if its in production build *or* you remove it it will trigger useEffect only once". Sorry. – Drew Reese Apr 13 '22 at 22:05

2 Answers2

1

You should add return in your function getCustomerList.

export async function getCustomerList() {
    return axios.get("http://localhost:8080/customer", { params: { id: 1 } });    
}

And get data like the following:

      const res = await getCustomerList();
      setCustomers({ res.data.customers });
Liki Crus
  • 1,901
  • 5
  • 16
  • 27
0

Probably React.StrictMode is firing the useEffect twice as for returning the values you should probably just do as the other answer ( @Liki Crus) suggests

miyav miyav
  • 338
  • 1
  • 5
  • 18
  • I don't think this is the case since the `useEffect` hook has an empty dependency array. Seems something is mounting the component twice. – Drew Reese Apr 13 '22 at 22:04
  • @DrewReese if dependency array is empty it fires once on render of component and it gets rendered twice because of `React.StrictMode` – miyav miyav Apr 13 '22 at 22:04
  • See [detecting unexpected side-effects](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects), it's not one of the double invoked functions. Or check this [answer](https://stackoverflow.com/a/61053571/8690857) for more in-depth explanation between "render" and "render to the DOM". – Drew Reese Apr 13 '22 at 22:07
  • but render is triggered twice and its triggering useEffect on render. – miyav miyav Apr 13 '22 at 22:09
  • you can read about that here https://stackoverflow.com/questions/60618844/react-hooks-useeffect-is-called-twice-even-if-an-empty-array-is-used-as-an-ar#:~:text=company%20blog-,React%20Hooks%3A%20useEffect()%20is%20called%20twice%20even%20if%20an,is%20used%20as%20an%20argument&text=Bookmark%20this%20question. – miyav miyav Apr 13 '22 at 22:10
  • Thanks. That other answer appears to be in agreement with the answer I linked you. "render" triggered twice, yes, during the "render phase", the `useEffect` hook is once per *render to the DOM*, i.e. the "commit phase", no matter what. Cheers. – Drew Reese Apr 13 '22 at 22:21