我正在使用Hooks中的useContext和useReducer和useEffect中的AsyncStorage.setItem,以在状态更新时保存数据。在重新加载应用程序时,我想确保使用AsyncStorage.getItem获取保存的数据并将其添加到初始状态。
我尝试将带有异步功能的init函数添加为useReducer的第三个属性,但仍然没有用接收到的数据替换初始数据。请通过下面的代码和帮助。
谢谢您!
当前可以将数据保存到AsyncStorage的代码
const [user, dispatch] = useReducer(userReducer, {});
useEffect(() => {
AsyncStorage.setItem('user', JSON.stringify(user))
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}
下面是我尝试的代码,但是无法将现有数据保存为初始数据。
const getUser = async function() {
const userData = await AsyncStorage.getItem('user')
console.log("parse");
console.log(userData);
console.log("parsed data");
console.log(JSON.parse(userData));
return userData ? JSON.parse(userData) : {};
}
export const UserContext = createContext();
const UserContextProvider = (props) => {
const [user, dispatch] = useReducer(userReducer, {}, getUser);
useEffect(() => {
console.log("context");
console.log(JSON.stringify(user));
AsyncStorage.setItem('user', JSON.stringify(user))
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}
但是您可以像下面一样使用useEffect loading state
const getUser = async () => {
try {
const user = await AsyncStorage.getItem('user')
return user ? JSON.parse(user) : {};
} catch (e) {
console.log('Failed to fetch the data from storage');
}
}
export const UserContext = createContext();
const UserContextProvider = (props) => {
const [isLoading, setIsLoading] = useState(true);
const [user, dispatch] = useReducer(userReducer, {});
// Loading initial Satte
useEffect(() => {
async function fetchUser() {
const user = await getUser();
setIsLoading(false);
dispatch({type: 'INIT_REDUCER', user}); // You must handle initReducer in reducer
}
fetchUser();
}, []);
useEffect(() => {
if(user) {
// This check is required to avoid initial writing to asyncStorage
console.log("context");
console.log(JSON.stringify(user));
AsyncStorage.setItem('user', JSON.stringify(user))
}
}, [user]);
if(isLoading) {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}
const getUser = async () => {
try {
const user = await AsyncStorage.getItem('user')
return user ? JSON.parse(user) : {};
} catch (e) {
console.log('Failed to fetch the data from storage');
}
}
export const UserContext = createContext();
const UserContextProvider = (props) => {
const [user, dispatch] = useReducer(userReducer, {});
// Loading initial Satte
useEffect(() => {
async function fetchUser() {
const user = await getUser();
dispatch({type: 'ADD_USER', user});
}
fetchUser();
}, []);
// Update AsyncStorage when user is updated
useEffect(() => {
// This check is required to avoid initial writing to asyncStorage
if(user) {
AsyncStorage.setItem('user', JSON.stringify(user))
}
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}