最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Where to set cookie in Isomorphic Redux Application? - Stack Overflow

programmeradmin2浏览0评论

I have 3 general questions about redux and isomorphic application:

  • What is the best way to share 'runtime' data between client and server? For instance, when the user logged in a distant API, I store the session object in cookies. In that way, next time the client requests my front-end, the front-end server can read the cookies and initialize the redux store with it's previous session. The downside of this is that the client HAS to validate/invalidate the session on boot (eg in componentDidMount of the root component). Should I request the session server side rather than read it from cookies?
  • Where should I execute the operation of cookie storing, in action creators or in reducers? Should I store the cookie in my reducer that handle the user session?
  • Where should I execute the operation of redirect the user (via react-router)? I mean when my user is successfully logged in, from where should I dispatch the redirect action (from the loginActionCreator once the login promise is resolved?, somewhere else? )

Thanks in advance.

I have 3 general questions about redux and isomorphic application:

  • What is the best way to share 'runtime' data between client and server? For instance, when the user logged in a distant API, I store the session object in cookies. In that way, next time the client requests my front-end, the front-end server can read the cookies and initialize the redux store with it's previous session. The downside of this is that the client HAS to validate/invalidate the session on boot (eg in componentDidMount of the root component). Should I request the session server side rather than read it from cookies?
  • Where should I execute the operation of cookie storing, in action creators or in reducers? Should I store the cookie in my reducer that handle the user session?
  • Where should I execute the operation of redirect the user (via react-router)? I mean when my user is successfully logged in, from where should I dispatch the redirect action (from the loginActionCreator once the login promise is resolved?, somewhere else? )

Thanks in advance.

Share Improve this question asked Jan 15, 2016 at 23:42 CnodeCnode 5571 gold badge5 silver badges18 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 6

I managed to get a really neat app structure. Here's what I found for each questions:

  • I only share between my client and front-end server the API server token via cookies. Each time the client request the site. The front-end server calls the API server to validate the session. If these servers are on the same network it's really fast (< 5ms). I also prefetch some useful data for the client on the server before the initial render. I manage to get my application loaded and ready (javascript loaded) in the client in 600ms. It is pretty decent.

  • The action of storing the cookie is in my actions creators. As Ethan Clark said, we must keep reducers pure. It's much more easier to test.

  • I still dispatch the redirect in my signin creator once the user is authenticated. I guess it's easier to test than to dispatch the action after the promise resolution in component or elsewhere.

In fact, keeping this in mind allows us to have an app really easy to test (expect for the actions creator where you must have ton of spies).

Hope it will help someone.

Thanks for participating.

Question 2: you should execute cookie storing in your action creator. Reducers must remain pure functions.

I'm really sorry that I don't know the answers to 1 & 3, but I hope that this helps!

You should probably break your questions up into three different stack overflow questions since they're all a little different.

I agree with Ethan, your reducers should be pure with no side effects. That's the goal (aka best practice) anyway. However, Ben Nadel has been exploring questions along these lines and suggests creating a workflow layer to manage business logic rather than placing that burden on the store. You should check out his Managing Locally Cached Data with Redux in AngularJS article for more information about that.

Cookies are synchronous - you can either hydrate and subscribe to your store or make a meta reducer which wraps around the reducer before it is added to createStore. Here's quick example of both below:

//first option
 const Cookie = require('js-cookie');
const loadState = (key) => Cookie.getJSON(key);
const saveState = (nextState, key) => Cookie.set(key, nextState);
const persistedState = loadState('todos');
const store = createStore(
  todoApp,
  persistedState
);

store.subscribe(throttle(() => {
  saveState({
    todos: store.getState().todos,
  }, 'todos');
}, 1000));

//second option - meta reducer
// usage  
    const Cookie = require('js-cookie');

    export function cookieMeta (
      key: string,
      reducer: any,
      expiry: Date | number = 365,
      path: string = '/',
      domain: string = window.location.hostname): Function {
      return function(state: any, action: any): any {
        let nextState = reducer(state, action);
        let cookieState = Cookie.getJSON(key);

        if (action.type.includes('DELETE')) {
          Cookie.remove(key);
        } else if (!nextState && cookieState || action.type === '@@redux/INIT') {
          nextState = cookieState;
        } else if (nextState && nextState !== cookieState) {
            Cookie.set(key, nextState, { expires: expiry, path: path, domain: domain, secure: process.env.local });
        }
        return nextState;
      };
    };
// how to implement the meta reducer
import { todos } from './todos';
import { cookieMeta } from './middleware/cookieMeta';
export function TODOS_REDUCER (state: any, action: any) {
    return cookieMeta('todos', todos)(state, action);
}
export const todoApp = combineReducers({ todos: TODOS_REDUCER  })
发布评论

评论列表(0)

  1. 暂无评论