skip to Main Content

I’ve been building a React app for a while now and have been testing responsiveness across multiple devices.

The React app itself works perfectly fine on my local machine. When accessing the React instance over the network, all HTTP requests fail because it wants to send HTTP requests to port 3000 instead of port 5000 which is what my Node.js server is running on.

[1] Compiled successfully!
[1]
[1] You can now view client in the browser.
[1]
[1]   Local:            http://localhost:3000
[1]   On Your Network:  http://192.168.1.122:3000
[0] [nodemon] starting `node server.js`
[1] Compiled successfully!
[1] webpack compiled successfully
[0] Server is running on port 5000
[0] MongoDB Connected!

Example of a request in the React app

  // Submit application to database
  const storeAndSubmit = (formData) => {
    try {
      // eslint-disable-next-line
      const res = axios({
        method: 'post',
        headers: {
          'Content-Type': 'application/json',
        },
        url: 'http://localhost:5000/api/applications',
        data: formData,
      });
      dispatch({
        type: APPLICATION_SUCCESS,
        payload: formData.pageNumber,
      });
    } catch (err) {
      dispatch({
        type: APPLICATION_FAIL,
      });
    }
  };

Because I don’t know what IP address React will choose when running my start script, I can’t just hard code the IP address into the request. Is there a React environment variable that can be accessed that has the current local network IP address after the start script has been run? If so, I can use that in my HTTP requests and I think that might work.

Error example over the network

xhr.js:210          POST http://192.168.1.122:3000/api/applications 404 (Not Found)

8

Answers


  1. I will assume if you specify the React port while starting your app, you will be able to solve this issue and correct me if I am wrong.

    You can just do this on Linux:

    PORT=3006 react-scripts start
    

    Or this on Windows:

    set PORT=3006 && react-scripts start
    

    Check this answer.

    Login or Signup to reply.
  2. One thing you can do is proxy your requests by adding the following to your package.json file: "proxy": "http://localhost:5000",

    Now in your fetch or Axios calls you can use the following URL '/api/applications' instead of 'http://localhost:5000/api/applications'

    Login or Signup to reply.
  3. You should not use a domain at all:

    url: '/api/applications',
    

    or

    url: 'api/applications',
    

    The former dictates api to be served from the domain’s root, and the latter requires api to be served from the current page’s path. In both cases, schema, domain, and port will be inherited from the current page’s URL.

    Details are in RFC 2396.

    It allows you use your code without changes on any domain, any port, as the hosting architecture is not of the frontend app’s concern.

    Login or Signup to reply.
  4. Make a .env file and maybe try this:

    REACT_APP_API_ENDPOINT=http://192.168.1.blablabla
    

    You can also do:

    "scripts" : {
       "start": "REACT_APP_API_ENDPOINT=http://localhost.whatever npm/yarn start"
       "start-production": "REACT_APP_API_ENDPOINT=http://production.whatever npm/yarn start"
    }
    

    It was taken from How can I pass a custom server hostname using React?.

    Login or Signup to reply.
  5. Firstly, test if the backend API is working or not via Postman.

    http://192.168.1.122:5000/ should work on your case.

    =========================================================

    After it

    Try this code on your frontend after checking the backend is working correctly with Postman.

    const api = axios.create({
        baseURL: "http://192.168.1.122:5000/api/",    //PLEASE CONFIRM IP.
        headers: {
            'Content-Type': 'application/json',
        },
    });
    
    const submitApi = async (formData) => api.post('/applications', formData);
    
    const storeAndSubmit = async (formData) => {
        try {
            const {data} = await submitApi(formData);
            if(!!data) {
                dispatch({
                    type: APPLICATION_SUCCESS,
                    payload: formData.pageNumber,
                });
            } else {
                dispatch({
                    type: APPLICATION_FAIL,
                });
            }
        } catch(e) {
            dispatch({
                type: APPLICATION_FAIL,
            });
        }
    }
    
    Login or Signup to reply.
  6. You are having a networking issue, so let’s go over it in detail.

    You have two processes running on your development machine:

    • a Node.js HTTP server serving the HTML file which loads the React app on localhost:3000. Let’s call this AppServerProcess
    • a Node.js HTTP server running a controller/driver for the database on localhost:5000. Let’s call this DbServerProcess

    So what happens when you are requesting the web application from another device in the network?

    The device will make an HTTP request to http://192.168.1.122:3000, where the AppServerProcess will handle the request and respond with the HTML content and the relevant scripts and assets, which will be loaded by the browser. The code in the JavaScript scripts (the web application), will have the fetch code with a URI of http://localhost:5000, which the device will resolve into itself, where it will fail to find anything.

    Now, the computer running both processes (DbServerProcess and AppServerProcess) has at least one IP address on the local network, which is 192.168.1.122. This means that if the DbServerProcess is running on localhost:5000, it should also be available on 192.168.1.122:5000, so the URI that should be hardcoded on fetch is http://192.168.1.122:5000/api/applications.

    Note that this will also work when working locally, as the IP address will resolve to itself.

    Also note that if the computer running both processes has DHCP configured, this IP address may change subject to that configuration, where you seem to have a misconception of what is happening, because it’s not React that chooses that, and it’s not even the AppServerProcess; it’s the OS which has at least one network interface that has a local IP address assigned by the DHCP server running on the router. If you want this to be static, then that is an OS configuration (pretty straight forward on both Windows, macOS and Linux).

    Look for "setting static IP address on {operating_system_name}".

    Login or Signup to reply.
  7. Look into cors-npm for your backend server because that maybe the reason for not connecting.

    Later you can maybe use Cloudflare Tunnel for your web server and use that address to access your web server in the react app. The link can be provided as an environment variable for the react. see setup react env variable

    Login or Signup to reply.
  8. I think you should check the response on the browser in the device you want to connect to the app from.

    With the 404 code, the potential reason may be that the device and your computer are not using the same Wi-Fi modem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search