[React] How to fetch data from express without using router?

I’m trying to render data from express server with real time graph on React.
Something like below and it seems like work.
But I wonder if It is Okay to fetch data with specific router(’/test’).
I feel like somebody will abuse the url and sniff my data.
And worried about the performance too.

Anybody can help me to find answer?

//server.js (express)

app.get('/test', (req, res, next) => {
        res.json({value: Math.random()});
    })
})

//client.js (react)

componentDidMount() {
    setInterval(() => {
        fetch('/test').then(res => res.json())
                      .then(res => {
                          this.setState(
                            {val: res.value}
                          )
                      });
    }, 1000);
}

How else would you get remote data except for fetch-ing it from some server (in this case the Express server you’ve created)? The point of writing a single page app is that it is literally a single HTML page. With an SPA you don’t have a router in a server serving different pages, you have to make AJAX requests (ie using fetch) to get data, there isn’t really any other option.

eg get the data that you are displaying using React? If you prevent them from seeing the data, then they can’t see the graph :man_shrugging: You can add authorization and authentication to your app so that you limit who can see it, but the graph is just the data printed out, so once they can see it they have the data.

It’s fine. It’s called long polling and it’s the easiest way to subscribe to data. It may have some performance implications, but you find out if that’s an issue by running the app under load and profiling it, not by preemptively guessing: the two alternatives are much more complex to implement, so you need a very good reason to dump the simple option.

The alternatives:

  • Websockets work well but tend to be a little bit of a pain to set up and manage (need work on both client and server code). They aren’t HTTP either. They open a persistent connection to the server, so you don’t need to keep requesting the data on the client while that’s open, it can just be kept in sync
  • Server Sent Events (SSE) are much simpler, they’re HTTP, but still need a little bit of work (client and server) and aren’t totally supported in all browsers as of now (though that may not be an issue). You make a normal GET request like you’re doing at the minute, but the server doesn’t close the connection and sends updates to the client
1 Like

On the web you normally have [client]—[server] relationship, where you are the server and user is the client (running your script). If your endpoint on the server will only give away information that will be displayed publicly then it’s totally fine to keep this endpoint open to anyone as there won’t be any difference.

Re performance, one thing to be worry about is that you component might be mounted and unmounted couple times each time creating intervals causing memory leak. You need to remove intervals or any listeners in componentWillUnmount()

2 Likes

How else would you get remote data except for fetch -ing it from some server

What if i configured react and express at the same server?
Can’t i get data from express by export module or something else without passing the network?

If you prevent them from seeing the data, then they can’t see the graph :man_shrugging:

I understood this part. But i want to hide the data shown on ‘/test’ url.
Is there other way to send data without showing the strings on webpage?
eg) not res.send() or res.json(), what else can be?

Websockets work well but tend to be a little bit of a pain to set up and manage

What is the benefit of using Websocket? If i can persevere in setting up and manaing, Is it worth to use ?
Can it be faster than Long Polling?

I know how to remove the event listener like below

componentWillUnmount() {
    document.removeEventListener('keydown', this.handleKeyPress)
  }

but i don’t know how to remove the fetch or interval…
Is clearInterval() enough like below?

componentDidMount() {
    var intervalID = setInterval(() => {
        fetch('/test').then(res => res.json())
                      .then(res => {
                          this.setState(
                            {val: res.value}
                          )
                      });
    }, 1000);
}

componentWillUnmount() {
  clearInterval(intervalID);
}
  1. I feel bad when i use var intervalID
    Is it the only way to get interval ID and clear?
  2. If i use function-type react component + UseEffect(), does it include both of componentDidMount() and componentWillUnmount so that it automatically get interval ID and clear it?

Ok, so a few things:

You already have them on the same server (ie a computer that manages access to something over a network).

A client requests the HTML/JS/etc, which gives them their app in the browser. The code in the app then requests more data from the server every second.

By definition, you can’t avoid using the network, it’s a web application. Asking for data over the network it literally the point. If you don’t use the network it’s not going to do anything.

If you don’t want to send the data, don’t send the data. If you need to send the data, you have to sent the data. There isn’t a choice here, you’re building a web app that displays data in real time so if you want the app to actually do anything you need to actually get it to fetch data.

As I said, you can put authentication and authorization in place to make people need to log in somehow to use the application, but you still actually have to fetch the data to be able to display data. Just to go back to this:

You are giving the external world access to some resource at https://my-app/test, that’s literally the point of you making the application. Someone “sniffing” the data is the whole point, there’s no point building the thing in the first place if they can’t look at the data

It’s more efficient, not sure what you mean by “faster”. But in your case I would strongly advise sticking to the simple solution until you understand what you’re doing. It will add a lot of complexity.

It’ll work when adjusted as per the advice from @snigo , but there are very slight complications when used with React

See here, for example:

On cancellation you would probably also want to abort the fetch request using an AbortController: you create a new one when the component mounts, then when the component unmounts you tell it to abort any fetch requests currently processing.

1 Like

Thank you so much @DanCouper !
Your advices helped me a lot!

Lastly, I have a question about this place FCC.
I was planning to go to Onsite-bootcamp this year, but cuz of COVID19, I’m stucked in my country…
However, This place FCC is amazing if i can get good advice like this!
I feel like I’m tranning at Onsite-bootcamp already.

Are you a manager of this FCC? or just high level camper?