使用useReducer时如何从AsyncStorage获取数据并将其添加到初始状态?

问题描述 投票:0回答:2

我正在使用Hooks中的useContextuseReduceruseEffect中的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>
  );
}
reactjs react-native async-await react-hooks asyncstorage
2个回答
1
投票
要使用reducer的初始状态需要同步。由于asyncStorage不是同步API,因此您实际上无法将值传递为initialState

但是您可以像下面一样使用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> ); }

0
投票
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> ); }
© www.soinside.com 2019 - 2024. All rights reserved.