Redux state persistence with a database

2019-03-08 15:58发布

问题:

From the discussion here it seems that the state of Redux reducers should be persisted in a database.

How does something like user authentication works in this instance?

Wouldn't a new state object be created to replace the previous state in the database for every user (and their application state) created and edited?

Would using all of this data on the front end and constantly updating the state in the database be performant?

Edit: I've created an example Redux auth project that also happens to exemplify universal Redux, and realtime updating with Redux, Socket.io and RethinkDB.

回答1:

From the discussion here it seems that the state of Redux reducers should be persisted in a database.

To persist the state or not, it's likely not a concern of Redux at all. It's more up to application logic.

If something happens in an application, like data upload to server, obviously you need to save state (or a slice of the state to a server).

Since network calls are asynchronous, but Redux is synchronous - you need to introduce additional middleware, as redux-thunk or redux-promise.

As sign-up example, you likely need that actions,

export function creatingAccount() {
  return { type: 'CREATING_ACCOUNT' };
}

export function accountCreated(account) {
  return { type: 'ACCOUNT_CREATED', payload: account };
}

export function accountCreatingFailed(error) {
  return { type: 'ACCOUNT_CREATING_FAILED', payload: error };
}

export function createAccount(data, redirectParam) {
  return (dispatch) => {
    dispatch(creatingAccount());

    const url = config.apiUrl + '/auth/signup';

    fetch(url).post({ body: data })
      .then(account => {
        dispatch(accountCreated(account));
      })
      .catch(err => {
        dispatch(accountCreatingFailed(err));
      });
  };
}

Some portion of state, e.g. user object after authorization, might be stored to localStore and re-hydrated on next application run.



回答2:

Those are valid concerns. Using localStorage to persist state on the frontend might be a better strategy. You can implement this using middleware, for example:

import {createStore, compose, applyMiddleware} from 'redux';

const localStorageMiddleware = ({getState}) => {
  return (next) => (action) => {
    const result = next(action);
    localStorage.setItem('applicationState', JSON.stringify(
      getState()
    ));
    return result;
  };
};

const store = compose(
  applyMiddleware(
    localStorageMiddleware
  )
)(createStore)(
  reducer,
  JSON.parse(localStorage.getItem('applicationState'))
)

If you're concerned about the enemy accessing the user's laptop and stealing credentials from it you could persist state to the backend when the user leaves the page (Navigator.sendBeacon() might be helpful here) & store it in the session.