0

This is a re-write of a previous post I made since I am able to reproduce the same problem using much simpler example.

I've created a simple app using npx create-react-app. I added logging logic to my App.js file as follows.

import logo from './logo.svg';
import './App.css';

function App() {
  console.log("###? App()");

  const logStuff = () => {
    console.log("###? Logging stuff")
    fetch("https://httpbin.org/post", {
      method: 'POST',
      body: JSON.stringify({error: "hello", message: "there"}),
    })
      .then(() => console.log('###? useLog() response'))
      .catch((error) => {
        console.error('###? Failed to send log with error: ' + error);
      });
  }

  return (
    <div className="App">
      {logStuff()}
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo"/>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

When I launch the app I get the following logs:

###? App() App.js:5
###? Logging stuff App.js:8
###? useLog() response App.js:9
###? useLog() response

In the network tab I see the following: enter image description here

The App() function is called once. The logStuff() function is called once; but in the network console I can see two requests go out to that URL and I don't understand why.

10
  • 1
    React is free to re-render your components (and call the hooks) as many times as it feels like, you are not guaranteed to not re-render. Put in a conditional check to avoid extra requests. Also, in general you should put side effects in a useEffect hook. Commented Aug 28, 2021 at 21:57
  • How are you using this function? like useLog()("error","message")? Commented Aug 28, 2021 at 22:02
  • In the component I bring it in by const log = useLog(); then I use it as log.error('error', 'error-description); Commented Aug 28, 2021 at 22:06
  • Interestingly you are not using any hooks. You need to keep your error object in the state with useState hook and as @JaredSmith mentioned, you need to use useEffect with the error state as a dependency. Your API call will happen inside the useEffect hook. If that's not the concept, share the code where you are calling the useLog(), after all, it's just a function. Commented Aug 28, 2021 at 22:16
  • @SanishJoseph OP is using useContext. Commented Aug 28, 2021 at 22:31

1 Answer 1

1

You've put logStuff function in your return statement, which is why you're experiencing this behaviour. Remember as a good practice return statement of a component should only return JSX/Components and should not be used for any calls. If you're running a function inside return statement, it should return JSX/Component.

This is the right way.

import './App.css';

function App() {
  console.log("###? App()");

  useEffect(() => {
     logStuff() //this should be regular practice for side effects
  },[]) //useEffect would run once only. If you want to change it on condition then provide other arguments to the array.

  const logStuff = () => {
    console.log("###? Logging stuff")
    fetch("https://httpbin.org/post", {
      method: 'POST',
      body: JSON.stringify({error: "hello", message: "there"}),
    })
      .then(() => console.log('###? useLog() response'))
      .catch((error) => {
        console.error('###? Failed to send log with error: ' + error);
      });
  }

  return (
    <div className="App">
      // {logStuff()} this was the problem, the function was calling on each render
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo"/>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.