有没有一种方法可以订阅 AsyncStorage
值的更改?我在应用程序中的一个地方保存了一个设置,它保存在 AsyncStorage
中,并影响其他所有屏幕。我需要观察这个值,以便更新所有屏幕。我尝试了 getValue
方法,但它似乎只能最初获取值,并且在更改时不会更新。
有没有一种方法可以订阅 AsyncStorage
值的更改?我在应用程序中的一个地方保存了一个设置,它保存在 AsyncStorage
中,并影响其他所有屏幕。我需要观察这个值,以便更新所有屏幕。我尝试了 getValue
方法,但它似乎只能最初获取值,并且在更改时不会更新。
const AppSettingsContext = React.createContext({})
const AppSettingsContextProvider = ({children}) => {
const [appSettingsInitialized, setAppSettingsInitialized] = useState(false)
const [appSettings, setAppSettings] = useState({}) // could use some default values instead of empty object
// On mount, get the current value of `appSettings` in AsyncStorage
useEffect(() => {
AsyncStorage
.getItem('appSettings')
.then(data => {
// If data is returned, the storage item existed already and we set the appSettings state to that.
if (data) {
setAppSettings(JSON.parse(data))
}
// If data is null, the appSettings keeps the default value (in this case an empty object)/
// We set appSettingsInitialized to true to signal that we have successfully retrieved the initial values.
setAppSettingsInitialized(true)
})
}, [])
// setSettings sets the local state and AsyncStorage
const setSettings = (key, value) => {
const mergedSettings = {
...appSettings,
[key]: value
}
// First, merge the current state with the new value
setAppSettings(mergedSettings)
// Then update the AsyncStorage item
AsyncStorage.setItem('appSettings', JSON.stringify(mergedSettings))
}
return (
<AppSettingsContext.Provider value={{
appSettings,
appSettingsInitialized,
setSettings,
}}>
{children}
</AppSettingsContext.Provider>
)
}
(请注意这是一个相当基本的版本,没有错误处理)
然后将您的应用程序包装在AppSettingsContextProvider中
const App = () => (
<AppSettingsContextProvider>
{/* Other components */}
</AppSettingsContextProvider>
)
然后从任何子组件中消费上下文:
const SomeChildComponent = () => {
const { appSettingsInitialized, appSettings } = useContext(AppSettingsContext)
// For example: wait until initial appSettings have been retrieved AsyncStorage,
// then use some value that you expect to be present in your business logic.
// In this case, setAppTheme would set the them color for the whole app, using a
// `theme` setting saved by the user.
useEffect(() => {
if (appSettingsInitialized) {
setAppTheme(appSettings.theme)
}
}, [appSettingsInitialized])
// Update settings like this for example
const updateThemeSetting = (newThemeValue) => {
setSettings('theme', newThemeValue) // eg 'dark', 'light', etc
}
}
当然,如果你使用react-native-easy-app帮助你使用AsyncStorage,你可以通过react-native-easy-app获得两个好处,
第一:你可以同步快速地访问AsyncStorage,并且支持直接访问字符串、布尔值、对象、数组等数据。代码片段
第二:当你修改任何AsyncStorage数据时,会有一个回调函数告诉你相应的数据变化。代码片段
详情请参考示例项目
你可以按以下方式使用它:
import { XStorage } from 'react-native-easy-app';
import { AsyncStorage } from 'react-native';
// or import AsyncStorage from '@react-native-community/async-storage';
export const RNStorage = {
token: undefined,
isShow: undefined,
userInfo: undefined
};
const initCallback = () => {
// From now on, you can write or read the variables in RNStorage synchronously
// equal to [console.log(await AsyncStorage.getItem('isShow'))]
console.log(RNStorage.isShow);
// equal to [ await AsyncStorage.setItem('token',TOKEN1343DN23IDD3PJ2DBF3==') ]
RNStorage.token = 'TOKEN1343DN23IDD3PJ2DBF3==';
// equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify({ name:'rufeng', age:30})) ]
RNStorage.userInfo = {name: 'rufeng', age: 30};
};
const dataSetChangedCallback = (data) => {
data.map(([keyStr, value]) => {
let [, key] = keyStr.split('#');
console.log('data has changed:', key, '<###>', value);
})
};
XStorage.initStorage(RNStorage, AsyncStorage, initCallback, dataSetChangedCallback);
您可以在 useEffect 中使用 AsyncStorage.getItem()
来监视组件挂载后的值。
useEffect(() => {
(async () => {
console.log(await AsyncStorage.getItem('YOUR_ITEM_KEY'));
})();
}, []);
使用此语法,您可以记录具有键“YOUR_ITEM_KEY”的项目。
如果您正在使用类组件,则可以像这样执行:
show = async () => {
console.log(await AsyncStorage.getItem('YOUR_ITEM_KEY'));
}
componentDidMount(){
this.show();
}