React Redux 状态将在使用 Nginx 更改路由时初始化

Posted

技术标签:

【中文标题】React Redux 状态将在使用 Nginx 更改路由时初始化【英文标题】:React Redux state going to init on route change with Nginx 【发布时间】:2020-09-15 22:16:39 【问题描述】:

我正在构建一个应用程序,其中React 作为前端,Postgres 作为 db,Express.js 作为 api,nginx 来管理路由。我的 React App 使用 React-RouterRedux 进行状态管理。我发现当路线改变时我的Redux 状态正在重置。我想这是因为我使用Ngnix 来路由请求并重新从头开始响应并且不保留状态。

我已经看到一些例子建议在同一个Docker 图像中使用ReactReact,方法是有两个阶段 - 构建用于反应,然后在第二步中将构建复制到Nginx 图像文件夹。然后使用这个镜像在 docker-compose 中定义一个服务。

如果我们在路由中也有 API 服务(这是一个单独的 Docker 图像),我们将如何处理这个问题?有没有更好的方法(生产级)?

Nginx 配置文件

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

【问题讨论】:

您使用的是哪个路由器?浏览器路由器、内存路由器还是哈希路由器?似乎所有路由器都可以在您的环境设置中工作。请仔细检查您是否使用 组件而不是 . 我正在使用浏览器路由器。 理想情况下,如果它是一个 SPA,获取另一条路由的请求不应该转到 Nginx。它应该在客户端处理 @gnujoow 可能是对的,听起来像一些触发整个网站重新加载的 你能展示你的反应代码,你是如何从一条路线切换到另一条路线的吗? 【参考方案1】:

有很多方法可以解决这个问题,这实际上取决于您要查找的内容。如果您说您想要生产质量,那么您甚至不一定会同时托管 API 并在完全相同的服务器上提供静态文件。

走这条路,你要么必须:

使用 nginx 分离 /api 请求并代理在不同端口上运行的 Express.js 项目 忘记 nginx 并使用 Express.js 也为任何不以 /api 开头的请求提供静态文件(但 Nginx 在处理静态文件方面要好得多,而且你不想占用你的节点.js 进程)

您会发现许多公司将其 API 托管在单独的子域上,例如 api.twitter.com

如果您这样做,您将在可扩展性、安全性、维护等方面拥有更大的灵活性。如果您继续在一台服务器上开发所有内容,您将需要更快地进行负载平衡并处理为您想要的任何其他服务提供更多代理。

至于您的 Redux 问题,您必须在某处进行正常重定向,而不是实际使用 React-Router,因为 React-Router 使用 javascript history 对象来更改 URL 路径和诸如此类的东西,这永远不会导致你的 Redux 状态正在清除。

如果你想导航到别处而不使用Link元素,那么你也可以只使用history.push("/anypathyouwant");

【讨论】:

以上是关于React Redux 状态将在使用 Nginx 更改路由时初始化的主要内容,如果未能解决你的问题,请参考以下文章

组件不会重新渲染,但 redux 状态已通过反应钩子更改

使用 react-navigation 时不发送 redux 状态

React + Redux + Router - 我应该为所有页面/组件使用一个状态/存储吗?

react--redux状态管理

React/Redux 存储状态未保存

Redux (with React) Reducer switch 语句不更新状态