为什么 redux-persist 不保留我的数据?
Why redux-persist doesn't persist my data?
我正在使用 redux 和 redux-persist 在 React Native 中为 Android 创建一个应用程序。
我想用 redux 将每个用户的 ID 存储在我的应用程序中,这样他们回来时就不需要再次登录。我制作了一个名为 handleUser 的 reducer,它允许用户登录。它在没有 redux-persist 的情况下工作得很好,但是当我使用它时,当我的 reducer 被调用时,商店不会更新。不知道在iOS.
上是不是一样
我已经尝试过这个:$rm -rf node_modules && $npm install
并且我还在我的 rootPersistConfig 中添加了 keyPrefix: ''
,我在多次询问中找到了这个解决方案,但它不起作用。请注意,我使用的是 react-navigation,即使我认为它与此无关。
这是我的 configureStore:
import { createStore } from 'redux'
import handleUser from './Reducers/userReducer'
import { persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const rootPersistConfig = {
key: 'root',
storage: storage,
keyPrefix: ''
}
export default createStore(persistCombineReducers(rootPersistConfig, { handleUser } ))
这是我的减速器:
const initialState = { ID: '' }
function handleUser(state = initialState, action) {
let nextState
console.log(action) //I added this debugger but the behaviour is expected, no error.
switch(action.type) {
case 'SIGN_IN':
nextState = {
...state,
ID: action.value.ID
}
return nextState || state
default:
return state
}
}
export default handleUser
这是允许登录的组件:
import React from 'react'
import { StyleSheet, View, Button } from 'react-native'
import { connect } from 'react-redux'
class SignIn extends React.Component {
_signIn() {
const action = { type: 'SIGN_IN', value: { ID: 'my_id' } }
this.props.dispatch(action)
console.log(this.props) //shows ID as undefined when using redux-persist
}
render() {
return (
<View style={styles.mainContainer}>
<Button
title='Sign in'
onPress={ () => this._signIn() }
/>
</View>
)
}
}
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
alignItems: 'center'
}
})
const mapStateToProps = state => {
return {
ID: state.ID
}
}
export default connect(mapStateToProps)(SignIn)
我希望当我在 SignIn 组件中显示 this.props
时,调用 reducer 后,我会找到值 my_id
。问题是它保持未定义状态。控制台没有显示任何错误。
我会检查一些事情。
- 记录持久存储,以查看它是否正在存储。
在 RND 控制台中键入 showAsyncStorageContentInDev()。
或使用以下方式登录:
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (error, stores) => {
stores.map((result, i, store) => {
console.log('log async: ',{ [store[i][0]]: store[i][1] });
return true;
});
});
});
很明显,您需要将上述代码放在代码中存储信息的位置。
- 确保您使用的是 redux-persist 提供的 PersistGate。
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
问题已解决! ID 保存完好,但我无法读取它。感谢 Aluminium22,他给了我一个更好的方式来阅读商店。我创建了一个名为 GetStore.js
的新文件,其中包含我在需要 ID 时使用的函数:
import AsyncStorage from '@react-native-community/async-storage'
export default function getStore(callback) {
return AsyncStorage.getAllKeys((err, keys) => {
return AsyncStorage.multiGet(keys, (error, stores) => {
const store = stores[1]
let parsedStore = JSON.parse(JSON.parse(store[1]).handleUser) //handleUser is my reducer
callback(parsedStore)
})
})
}
所以当我想阅读我的商店时:
import GetStore from 'your GetStore.js file path'
//...
GetStore( store => {
console.log(store)
})
我正在使用 redux 和 redux-persist 在 React Native 中为 Android 创建一个应用程序。 我想用 redux 将每个用户的 ID 存储在我的应用程序中,这样他们回来时就不需要再次登录。我制作了一个名为 handleUser 的 reducer,它允许用户登录。它在没有 redux-persist 的情况下工作得很好,但是当我使用它时,当我的 reducer 被调用时,商店不会更新。不知道在iOS.
上是不是一样我已经尝试过这个:$rm -rf node_modules && $npm install
并且我还在我的 rootPersistConfig 中添加了 keyPrefix: ''
,我在多次询问中找到了这个解决方案,但它不起作用。请注意,我使用的是 react-navigation,即使我认为它与此无关。
这是我的 configureStore:
import { createStore } from 'redux'
import handleUser from './Reducers/userReducer'
import { persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const rootPersistConfig = {
key: 'root',
storage: storage,
keyPrefix: ''
}
export default createStore(persistCombineReducers(rootPersistConfig, { handleUser } ))
这是我的减速器:
const initialState = { ID: '' }
function handleUser(state = initialState, action) {
let nextState
console.log(action) //I added this debugger but the behaviour is expected, no error.
switch(action.type) {
case 'SIGN_IN':
nextState = {
...state,
ID: action.value.ID
}
return nextState || state
default:
return state
}
}
export default handleUser
这是允许登录的组件:
import React from 'react'
import { StyleSheet, View, Button } from 'react-native'
import { connect } from 'react-redux'
class SignIn extends React.Component {
_signIn() {
const action = { type: 'SIGN_IN', value: { ID: 'my_id' } }
this.props.dispatch(action)
console.log(this.props) //shows ID as undefined when using redux-persist
}
render() {
return (
<View style={styles.mainContainer}>
<Button
title='Sign in'
onPress={ () => this._signIn() }
/>
</View>
)
}
}
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
alignItems: 'center'
}
})
const mapStateToProps = state => {
return {
ID: state.ID
}
}
export default connect(mapStateToProps)(SignIn)
我希望当我在 SignIn 组件中显示 this.props
时,调用 reducer 后,我会找到值 my_id
。问题是它保持未定义状态。控制台没有显示任何错误。
我会检查一些事情。
- 记录持久存储,以查看它是否正在存储。 在 RND 控制台中键入 showAsyncStorageContentInDev()。 或使用以下方式登录:
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (error, stores) => {
stores.map((result, i, store) => {
console.log('log async: ',{ [store[i][0]]: store[i][1] });
return true;
});
});
});
很明显,您需要将上述代码放在代码中存储信息的位置。
- 确保您使用的是 redux-persist 提供的 PersistGate。
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
问题已解决! ID 保存完好,但我无法读取它。感谢 Aluminium22,他给了我一个更好的方式来阅读商店。我创建了一个名为 GetStore.js
的新文件,其中包含我在需要 ID 时使用的函数:
import AsyncStorage from '@react-native-community/async-storage'
export default function getStore(callback) {
return AsyncStorage.getAllKeys((err, keys) => {
return AsyncStorage.multiGet(keys, (error, stores) => {
const store = stores[1]
let parsedStore = JSON.parse(JSON.parse(store[1]).handleUser) //handleUser is my reducer
callback(parsedStore)
})
})
}
所以当我想阅读我的商店时:
import GetStore from 'your GetStore.js file path'
//...
GetStore( store => {
console.log(store)
})