Looking back with a lot more experience, I think I can answer this question.
What confused me was that developers go through all the hassle of back-end libraries and route configurations for APIs. It seemed like a very roundabout way to write code.
To understand why developers do this, you have to have a fundamental understanding of the back-end and front-end, which are, at a primitive level, the same.
In the web, people use domains and add routes to them to create URLs. These URLs, when visited, send requests to a server, and the server executes code accordingly. Web frameworks just allow developers to do this more efficiently and easily. When you go to a URL and receive a response from the server, that response is the server's message, (usually) packaged by the framework. This means that everything from entirety of Google, to plain unformatted JSON, is primitively plain text with some additional info (headers) that tell your browser how to handle the response.
To get back to what I was asking, the reason you can't just write back-end code in the front-end, is because when the server (the framework you use for front-end code) sends a response, it is just sending HTML with some `script` tags that run Javascript. If you wanted to write back-end logic in the front-end, all the code would have to be run through said `script` tags. This is referred to as client side code.
The problem with client-side code is that clients shouldn't have access to server operations. If you are trying to say insert a document into your database, process a payment, or run any sort of sensitive/time consuming/intensive code, doing so client-side would be unsafe and inefficient.
Instead, what you can do is run back-end code. The same way front-end frameworks take code you write and serve it to the world by "packaging" it, back-end code is just code that runs alongside the packaging. When you send a request to a server, that server executes code locally, and then sends a response based what the local code evaluates. This solves the problem of running sensitive/time consuming/intensive code, because the code runs on the server, before the evaluation is returned to the user.
The reason back-end and front-end frameworks are separate (with frameworks like Next.js being the exception), is just a matter of convenience. Sending code as user-friendly HTML presents different challenges than sending it as plain text or JSON. Frameworks just make it easier to do what you need to do with each.
In short, frameworks *can* run code in the "background" (back-end), but they usually shouldn't.
Please consider clarifying your question, because I don't know also if you use next.js or nuxt.js.
Angular, React, Vue.js are JavaScript frontend frameworks/libraries, which means they are using JavaScript language.
The websites on the Internet contain HTML, CSS, JavaScript Vanilla code.
The application you developed using React.js needs to use React.js library source code, and then you need the React.js code to be compiled to JavaScript Vanilla code because the browser at the end needs a JavaScript native code that it can read.
When I need to see your hosted website, I need to write the domain name to see it, so the HTTP request at the end goes to the server which is hosting your react app, thus if your react application contains just a **static content**, for example, a landing HTML page, then there is no need for server-side rendering from Express(Node.js), Ruby, PHP, Java,...
What I mean by static content is content that doesn’t change in response to different users, all of them will get the same content.
Notice you can host a static website in Github and you still don't need any server-side rendering...
Let's have a small application for a better explanation:
If you developed a Portfolio that contains a description of yourself, images of your projects, skills, then here there is no need for a server-side rendering.
But if you developed a system that lets a user who has permission to create a short link from a full URL, then you need a backend server(like Java, Ruby, C#, PHP,...) to host the logic code in order to generate a tiny URL from the full URL, and then save it in a Database, that way any user can click the generated tiny URL then this request goes to your backend server which needs to redirect the user with correct full URL, an application like this cannot be done using React.js alone, you need a server to handle the logic.
Returning to your answering your question: ***"So, I'm curious to know what is the benefit of serving my react applications from an express server."***
If you have static content you can avoid using Express, but if you think your application needs some backend logic in the future, then Express or any other backend framework will help you in that.
*Notice when you have a static website, and you tried to edit the content of it, the users which already visited your website, their browser might cached your website content unless (they disabled this option in their browser), so if your website is cached in users' browsers they might not get the updated content unless you changed the static website file name for example by adding ?092130123 to file name in order to let the users' browser download the updated data