rematch / rematch

The Redux Framework
https://rematchjs.org
MIT License
8.47k stars 420 forks source link

Question: Using Rematch Persist #679

Closed lee-aaron closed 5 years ago

lee-aaron commented 5 years ago

I'm having trouble getting started using Rematch Persist. I update the state with something then I reload / close & open the app again but the state does not persist. I noticed on using the transform the inbound state when it serializes and persists that the state gets reset to an initial state. The outbound state when it rehydrates has the correct state. Am I setting it up correctly or is there something else I need to do?

store/index.js

/* global */
import { init } from '@rematch/core';
import createPersistPlugin, { getPersistor } from '@rematch/persist';
import createLoadingPlugin from '@rematch/loading';
import storage from 'redux-persist/es/storage';
import * as models from '../models';
import catalogTransform from './transforms/handleCatalog';

// Create plugins
const persistPlugin = createPersistPlugin({
  version: 2,
  storage,
  blacklist: [],
  transforms: [catalogTransform],
});
const loadingPlugin = createLoadingPlugin({});

const configureStore = () => {
  const store = init({
    models,
    redux: {
      middlewares: [],
    },
    plugins: [persistPlugin, loadingPlugin],
  });

  const persistor = getPersistor();
  const { dispatch } = store;

  return { persistor, store, dispatch };
};

export default configureStore;

transforms/handleCatalog

import { createTransform } from "redux-persist";

const handleCatalog = createTransform(
  // transform state on its way to being serialized and persisted.
  (inboundState, key) => {
    console.log(inboundState);
    let object = {};
    inboundState.coverImage.forEach((value, key) => {
      object[key] = value;
    });
    return {
      ...inboundState,
      coverImage: object,
      popularManga: [...inboundState.popularManga]
    };
  },
  // transform state being rehydrated
  (outboundState, key) => {
    console.log(outboundState);
    return {
      ...outboundState,
      coverImage: new Map(outboundState.coverImage),
      popularManga: [...outboundState.popularManga]
    };
  },
  { whitelist: ["handleCatalog"] }
);

export default handleCatalog;
semoal commented 5 years ago

I can't see anything wrong mate. Use standard persist, if that works, try step by step.

const persistPlugin = createPersistPlugin({
  version: 2,
  storage,
  blacklist: [],
  whitelist: ['catalogModel']
});

If that works, the problem may be your transform method, if the issue persist try to post it on redux-persist. Think that rematch plguin is just a wrapper of redux-persist. Our plugin only has like 20 lines

lee-aaron commented 5 years ago

Hi, Thanks for your response! I will ask them and see what the issue is. Another question I had was I'm not sure if I'm using redux devtools correctly with this application because I have this right now and I see dispatches being called but my console log methods inside the effects aren't being triggered. Am I missing something?

/* global */
import { init } from '@rematch/core';
import { composeWithDevTools } from 'remote-redux-devtools';
import createPersistPlugin, { getPersistor } from '@rematch/persist';
import createLoadingPlugin from '@rematch/loading';
import AsyncStorage from '@react-native-community/async-storage';
import * as models from '../models';
import catalogTransform from './transforms/handleCatalog';

// Create plugins
const persistPlugin = createPersistPlugin({
  version: 2,
  storage: AsyncStorage,
  blacklist: [],
  transforms: [catalogTransform]
});
const loadingPlugin = createLoadingPlugin({});

const configureStore = () => {
  const store = init({
    models,
    redux: {
      enhancers: [composeWithDevTools()],
    },
    plugins: [persistPlugin, loadingPlugin],
  });

  const persistor = getPersistor();
  const { dispatch } = store;

  return { persistor, store, dispatch };
};

export default configureStore;
import Manga from '../skeleton/model/MangaObject';

export default {
  namespace: "handleCatalog",

  /**
   *  Initial state
   */
  state: {
    source: null,
    popularManga: [],
    coverImage: new Map()
  },

  /**
   * Reducers
   */
  reducers: {
    getCurrentSource(state) {
      return {
        ...state
      };
    },
    setCurrentSource(state, source) {
      return {
        ...state,
        source: source
      };
    },
    handlePopularManga(state, payload) {

      let coverImage = state.coverImage || new Map();
      let popularManga = state.popularManga || [];

      coverImage.set(payload.manga.title.replace(/ /g, "_").toLowerCase(), payload.image);
      if ( popularManga.filter(e => e.title === payload.manga.title).length === 0 ) {
        popularManga.push(new Manga(payload.manga));
      }

      return {
        ...state,
        popularManga: popularManga,
        coverImage: coverImage
      }
    }
  },

  /**
   * Effects/Actions
   */
  effects: dispatch => ({
    getSource() {
      return this.getCurrentSource();
    },
    setSource(source) {
      console.log('setting source');
      return this.setCurrentSource(source);
    },
    handlePopular(payload) {
      return this.handlePopularManga(payload);
    }
  })
};
semoal commented 5 years ago

Your question is duplicated https://github.com/rematch/rematch/issues/419, and probably there's no solution, feel free to post any clue you find.

PrafullKumarB commented 2 years ago

Rematch reduced lot of reworks and its really easy to use Is there any why i can able to clear all models without including persisted models( or white list models) @semoal