Full-Stack React & Node.js - Get client & server talking
Tags: react, node, javascript, webdev
Published: 2022-06-27 22:21:21

---
series: Simply Learn Full-Stack React & Node.js
---

Finally, the fun part is here! All our components are in place and now we only need to change 1 component to get the server and client talking.

In **react-client**, edit **AddEditNote.js**, and replace the contents with this:

```jsx
import React, {useState, useEffect} from 'react';
import RenderData from "./RenderData";
import Form from './Form';

const AddEditNote = () => {
  const [note, setNote] = useState({});

  useEffect( () => {
    async function fetchData() {
      console.log('Calling fetch...')
      const response = await fetch('http://localhost:4011/note');

      if (response.ok) {
        console.log('Response received from server and is ok!')
        const {note} = await response.json();

        setNote(note)
      }
    }

    fetchData()
  }, [])

  return (
    <div>
      <RenderData
        data={note}
      />
      <Form
        entity={note}
      />
    </div>
  );
};

export default AddEditNote;
```

To test this you will need 2 shell/CLI programs.

Use one to run the server, in **node-server** folder, execute:

```shell
npm run start
```

The second in **react-client** folder, execute:

```shell
npm run start
```

Now, when your React site runs, and you click on "Edit Post" you will see a form with data that has been loaded from the server.

If you take a look at the shell/CLI where you ran your Node.js server you should see the requests logged by ***morgan***.

There's a problem here though!

![node server request log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b81klz8c6ue2tldxognn.JPG)

Each time we visit the form we see two GET requests on the server.

If you open the dev console in Chrome with F12 and go to the network tab you will also see duplicated requests here!

![Chrome network tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sucwr5guz8var4rp5gs0.JPG)

> Pro tip: if your Chrome network tab doesn't show what you expect, make sure the correct category is selected. Look at the second row in the image above and you will see "Fetch/XHR" selected.

Let's check the Chrome console to see what we've logged out:

![Chrome console logs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/453ajpxs6qkg1brerqdc.JPG)

Sure enough, we call fetch twice, and receive a response twice. What is going on here?

This kind of thing is quite common, and in apps with a very complex structure of many nested components, you might see the same requests repeated 10, 12 or more times.

This is due to the way React will re-render components when either the props or the state changes.  Which, of course is exactly what React is supposed to do. As developers we need to be careful when we fetch data inside, what is essentially, UI rendering code.

So, are we doomed? Do we just give up and go home?  

![Never Give Up toddler meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tad890up8el07ahie61f.JPG)

To fix this we need to keep track of requests that have been made, and cancel them when the component unmounts, and ignore any responses that might sometimes return from cancelled requests.

Edit **AddEditNote.js** again, to this code:

```jsx
import React, {useState, useEffect} from 'react';
import RenderData from "./RenderData";
import Form from './Form';

const AddEditNote = () => {
  const [note, setNote] = useState({});

  useEffect( () => {
    const abortController = new AbortController();

    async function fetchData() {
      console.log('Calling fetch...')
      try {
        const response = await fetch('http://localhost:4011/note', {
          signal: abortController.signal,
        });

        if (response.ok) {
          console.log('Response received from server and is ok!')
          const {note} = await response.json();

          if (abortController.signal.aborted) {
            console.log('Abort detected, exiting!')
            return;
          }

          setNote(note)
        }
      } catch(e) {
        console.log(e)
      }
    }

    fetchData()

    return () => {
      console.log('Aborting GET request.')
      abortController.abort();
    }
  }, [])

  return (
    <div>
      <RenderData
        data={note}
      />
      <Form
        entity={note}
      />
    </div>
  );
};

export default AddEditNote;
```

We use the `AbortController` as a signal passed as an option to the fetch request. When the component unmounts we abort any requests. And, just in case a request slipped through before being aborted, we check the abort state when a request returns.

> This bug is common in production code bases. With each user action triggering multiple fetch requests causing the server to make multiple DB requests, your servers might end up with 10 times the load they should have.

If you save and run the code again, you will see that duplicate requests are cancelled and we only hit the server with a single GET request each time we visit the form. Good job - bug fixed!

In the next part, we will explore other HTTP verbs to make data mutations on the server...

Code repo: [Github Repository](https://github.com/neohed/node-react-stack)