React'te Async işlevlerini kullanıma koymakEffect () hook

Oct 04 2020

GoogleMap API anahtarımı güvenli API'min arkasına gizlemek istediğim bir uygulamayı bitiriyorum. Niyetim, kimliği doğrulanmış bir kullanıcım olduğunu doğruladığımda API anahtarını aramaktır. Sorun, eşzamansız aramalar arasındaki değişikliklerin durum değişikliği ile yansıtılmamasıdır.

Yaptığım şey bu:

export default function App() {
  const [dateRange, setDateRange] = useState(initialDateRange);
  const [formState, updateFormState] = useState(initialFormState);
  const [user, setUser] = useState(null);
  const [googleApiKey, setGoogleApiKey] = useState(null);

  useEffect(() => {
    async function updateAuth() {
      try {
        await checkUser();
        await getGoogleApiKey();
        await setAuthListener();
      } catch (error) {}
    }
    updateAuth();
  }, []);

  async function checkUser() {
    try {
      const user = await Auth.currentAuthenticatedUser();
      setUser(user);
      if (user !== authenticatedUser) {
        updateFormState(() => ({
          ...formState,
          authenticatedUser: user
        }));
      }
    } catch (error) {
      console.log(error);
    }
  }

  async function getGoogleApiKey() {
    const googleApiUrl = `${process.env.REACT_APP_API_PATH}apikey?googleapikey=true`; 
    try {
      console.log('USER_USER_USER', user);
      const apiKey = await fetch(googleApiUrl, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          Authorization: user.signInUserSession.idToken.jwtToken
        }
      });
      console.log('GOT_GOOGLE_API_KEY', apiKey);
      setGoogleApiKey(apiKey);
    } catch (error) {
      console.log(error);
    }
  }

  async function setAuthListener() {
    Hub.listen('auth', (data) => {
      const event = data.payload.event;
      switch (data.payload.event) {
        case 'signOut':
          console.log('signing out...');
          console.log(event);
          updateFormState(() => ({
            ...formState,
            username: '',
            password: '',
            email: '',
            authenticatedUser: null
          }));
          break;
        default:
          break;
      }
    });
  }

Ama şu hatayı alıyorum:

USER_USER_USER null
App.js:78 TypeError: Cannot read property 'signInUserSession' of null
    at getGoogleApiKey (App.js:72)
    at updateAuth (App.js:42)

Bu yanlış paradigma ise, herhangi bir alternatifi takdir ederim!

Yanıtlar

4 Yuan-HaoChiang Oct 04 2020 at 08:33

Ne zaman setUserdenir, userdeğişken hala eski tutan user(bilgi nullbakılmaksızın bu durumda), async/await:

await checkUser();        // setUser(something) will not happen until next run
await getGoogleApiKey();  // user is still null
await setAuthListener();

Diğer bir seçenek, userdeğişiklik olduğunda başka bir efekt eklemek olacaktır :

useEffect(() => {
  if (user) {
     getGoogleApiKey();
  }
}, [user]);

Veya getGoogleApiKeyparametre ile çağırın :

const user = await checkUser(); // return user
await getGoogleApiKey(user);
await setAuthListener();

Mantık karmaşıklaştığından, useReducer kancasını denemenizi öneririm çünkü dispatch bu karmaşık ileri geri senaryoları basitleştirir.