React/Redux服务器端渲染初始状态

5
我有一个React/Redux应用程序,在本地存储中跟踪用户的身份验证状态。该应用程序也设置了服务器端渲染。当渲染初始应用程序状态时,我遇到了问题。我的服务器创建了一个新的store并发出SET_INITIAL_STATE操作。客户端的初始操作读取localStorage,并将已验证的信息传递给我的reducers。然而,由于我在本地存储中使用无状态JWT进行身份验证,因此服务器对这个登录状态一无所知。
由于此时服务器和客户端不同步,我遇到了以下错误:
"React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:"
这是有道理的,因为服务器正在尝试渲染未经身份验证的状态。
针对仅依赖于客户端访问的状态,接受的标准或实践是什么?

如果只有客户端可以访问它,那么你无法做到(至少我想不出好的方法)。你能做的最好的事情是在服务器上呈现一个非常简单的应用程序(或者是一些其他版本的应用程序,对于已认证的用户来说并不完全正确——例如,你可以有一个“加载”状态或类似的服务器呈现),以相同的方式初始化客户端应用程序,然后根据令牌重新呈现——但这基本上就是你已经在做的事情了(除了警告 :))。 - Michelle Tilley
2个回答

5
我发现楼主是对的,cookie存储是最好的选择。如果您正在使用React、Redux和Express构建通用应用程序,那么适合我的选项是https://github.com/eXon/react-cookie
基本上:
在您的服务器端代码中,您可以使用:
  import cookie from 'react-cookie';

  function handleRender(req, res) {
      cookie.setRawCookie(req.headers.cookie);

      // Create new Redux store instance
      const store = createStore(rootReducer, {
          username: cookie.load('username') || '',
          accessLevel: cookie.load('accessLevel') || userRoles.public,
      });

      //other react/redux/express related code
  }

在你的React应用程序中,在组件内部,你可以直接保存cookie:

  import cookie from 'react-cookie';

  //first parameter is anything you want, second is the data you want to save
  cookie.save( 'username', username );
  cookie.save('accessLevel', accessLevel);

如果您想像我一样存储一个对象,您可以传递JSON.stringify(your object)。cookie.load会自动解析它。在我的代码中,我从actions调用了cookie.save,但您可以在组件或任何抽象中直接调用它。

1
我找到了一个可行的解决方案。
不幸的是,诀窍在于将认证状态存储在 cookie 中,以便会话状态在请求时自动发送到服务器。

4
你可以发布你用来完成这个任务的代码/方法吗? - Boomer Rogers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接