【问题标题】:React native + redux-persist: how to ignore keys (blacklist)?React native + redux-persist:如何忽略键(黑名单)?
【发布时间】:2017-05-03 00:34:28
【问题描述】:

我使用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;
}
// ...

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

提前致谢!

【问题讨论】:

    标签: javascript reactjs react-native redux react-redux


    【解决方案1】:

    您必须为要保存的每个道具创建减速器。

    【讨论】:

      【解决方案2】:

      根据documentation,黑名单参数包含:'keys (read: reducers) to ignore',所以恐怕无法实现你想要的行为。您可以尝试自己实现该功能,但我认为该包的代码库实际上专注于将 reducer 列入黑名单而不是属性(请参阅this)。恐怕唯一的解决方案是为您的非持久键创建一个单独的减速器(根据我的经验,这并不麻烦)。

      【讨论】:

        【解决方案3】:

        使用转换来保存单独的字段,例如 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
          ]
        })
        

        【讨论】:

          【解决方案4】:

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

          例子:

          // 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
          }
          
          

          【讨论】:

            【解决方案5】:

            您可以为此使用 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
            };
            
            
            

            【讨论】:

              【解决方案6】:

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

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2018-05-23
                • 1970-01-01
                • 2018-03-28
                • 2019-10-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多