React native + redux-persist:如何忽略键(黑名单)?

React native + redux-persist: how to ignore keys (blacklist)?

我正在使用 redux-persist 存储我的设置,并且想忽略其中的一些设置以便在每次重新启动时重置它们,例如崩溃后。

可以将 reducer-names 数组添加为 blacklistwhitelist,但我想忽略特定的键,例如settings.isLoggedIn 而不是 settings.

// ...
function configureStore(initialState) {
    const store = createStore(
        RootReducer,
        initialState,
        enhancer
    );

    persistStore(store, {
        storage: AsyncStorage,
        blacklist: ['router', 'settings'] // works, 'settings.isLoggedIn' doesn't.
    }, () => {
        // restored
    });

    return store;
}
// ...

我是否必须创建另一个减速器或者有人可以解决这个问题吗?

提前致谢!

你必须为每个你想保存的道具创建 reducer。

根据 documentation, the blacklist parameter contains: 'keys (read: reducers) to ignore', so I am afraid it is not possible to implement the behaviour that you want. You can try and implement that functionality yourself, but I think the codebase of the package is really focused on blacklisting reducers instead of properties (see this)。恐怕唯一的解决方案是为您的非持久键创建一个单独的 reducer(根据我的经验,这并不是一件麻烦事)。

使用转换来保存单独的字段,例如 username in redux-form MyForm inside state.form.MyForm:

const formName = `MyForm`

const formTransform = createTransform(
  (inboundState, key) => {
    return {
      ...inboundState,
      [formName]: {
        values: {
          username: _.get(inboundState, `${ MyForm }.values.username`)
        }
      }
    }
  },
  (outboundState, key) => {
    return outboundState
  },
  { whitelist: [`form`] }
)

persistStore(store, {
  whitelist: [
    `form`
  ],
  transforms: [
    formTransform
  ]
})

一个简单的解决方案是将整个减速器保存在白名单中,然后在减速器中使用 'persist/REHYDRATE' 操作仅过滤您想要保留的键。

示例:

// configureStore.js
const persistConfig = {
  keyPrefix: 'webapp',
  whitelist: ['filters'],
}

// filtersReducer.js
const projectsBase = {
  [KEYS.SORT]: PROJECTS_SORT_TYPE.NAME,
  [KEYS.TEXT]: '',
}
const itemsBase = {
  [KEYS.SORT]: ITEMS_SORT_TYPE.INDEX,
  [KEYS.TEXT]: '',
}

const base = {
  [KEYS.PROJECTS]: projectsBase,
  [KEYS.ITEMS]: itemsBase
}

export const filters = (state = base, action) => {
  const { type } = action
  switch (type) {
    case PERSIST_REHYDRATE_ACTION_TYPE: {
      if (action.payload.filters) {
        const filters = action.payload.filters
        const projectsSort = _.get(filters, [KEYS.PROJECTS, KEYS.SORT])
        const itemsSort = _.get(filters, [KEYS.ITEMS, KEYS.SORT])
        const newBase = { ...base, 
                         [KEYS.PROJECTS]: {
                             [KEYS.SORT]: projectsSort
                         },
                         [KEYS.ITEMS]: {
                             [KEYS.SORT]: itemsSort
                         }}
        state = newBase
      }
    }
      break
    default:
      break
  }
  return state
}

您可以为此使用 Nested Persists

import { persistStore, persistReducer } from 'redux-persist';


const rootPersistConfig = {
  key: 'root',
  storage: storage,
  blacklist: ['auth']
}

// here you can tell redux persist to ignore loginFormData from auth reducer

const authPersistConfig = {
  key: 'auth',
  storage: storage,
  blacklist: ['loginFormData']
}

// this is your global config
const rootReducer = combineReducers({
  auth: persistReducer(authPersistConfig, authReducer),
  other: otherReducer,
})

// note: for this to work, your authReducer must be inside blacklist of 
// rootPersistConfig

const myReducerConfig = {
  key: "cp",
  storage: storage,
  blacklist: ["authReducer"],
  debug: true
};


正如 提到的创建一个单独的 reducer,这是一个不错的选择,如果我们遵循它并为错误创建一个单独的 reducer,我们可以简单地 return 一个空状态作为默认值;

const initialState = {
    error: null
}

export default errorReducer = (state = initialState, action) => {
    switch (action.type) {
        ...         
    
        default:
            return {
                ...state,
                error: null
            }
    }
}

这将在我们每次访问该站点时清除状态,因为默认情况下会将错误设置为空。