Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Redux state going to init on route change with Nginx

I am building an app with React as the front end, Postgres as db , Express.js as api and Nginx to manage routing. My react App uses React-Router and Redux for state management. I found that my Redux state was getting reset when the route changed. I guess this is because I am using Ngnix to route the requests and react starts up from the beginning again and without preserving the state.

I have seen examples suggesting using Nginx and React in the same Docker image by having two stages - a build for react and then copy the build to Nginx image folder in the second step. Then use this image to define a single service in docker-compose.

How will we handle this when we have API service also in the routing (which is a separate Docker image) ? Is there a better way of doing this (production grade)?

Nginx conf file

upstream client {
    server client:3000;  
}

upstream api {
    server api:5000;  
}

server {
    listen 80;

    location / {
        proxy_pass  http://client;
    }

    location /sockjs-node {
        proxy_pass  http://client;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    location /api/ {
        rewrite /api/(.*) /$1 break;
        proxy_pass  http://api;
    }
}

docker-compose.yaml

version: "3"
services:
  postgres:
    image: "postgres:latest"
    environment:
      - POSTGRES_PASSWORD=postgres_password
  api:
    build:
      dockerfile: DockerFile.dev
      context: ./server
    volumes:
      - /app/node_modules
      - ./server:/app
    environment:
      - PGUSER=postgres
      - PGHOST=postgres
      - PGDATABASE=postgres
      - PGPASSWORD=postgres_password
      - PGPORT=5432
    depends_on:
      - postgres
  client:
    stdin_open: true
    build:
      dockerfile: DockerFile.dev
      context: ./client
    volumes:
      - /app/node_modules
      - ./client:/app
    depends_on:
      - api
  nginx:
    restart: always
    build:
      dockerfile: DockerFile.dev
      context: ./nginx
    ports:
      - "3050:80"
    depends_on:
      - client
like image 244
vzurd Avatar asked Sep 16 '25 23:09

vzurd


1 Answers

There's a lot of ways to go about this and it really just depends on what you're looking for. If you're saying you want production quality then you wouldn't necessarily even be hosting both the API, and serving the static files on the exact same server.

By going that route, you either have to:

  • Use nginx to separate the /api requests and proxy your Express.js project running on a different port
  • Forget about nginx and use the Express.js to also serve the static files for any request that doesn't start with /api (but Nginx is way better at handling static files and you don't want to occupy your Node.js process)

You'll find that many companies host their API on a separate subdomain, ex api.twitter.com.

If you go about it this way, you'll have much more flexibility in scalability, security, maintenance, etc. If you continue developing everything on one server, you're going to need to be load balancing much sooner and dealing with more proxying for any other services you want.

As for your Redux issue, you must be doing a normal redirection somewhere and not actually using React-Router, because React-Router uses the JavaScript history object to make changes to the URL path and whatnot which should never result in your Redux state being cleared.

If you want to navigate elsewhere and not use Link element, then you can also just history.push("/anypathyouwant");

like image 80
Andre Avatar answered Sep 19 '25 15:09

Andre