Đưa các hàm Async vào sử dụng hookEffect () trong React
Tôi đang hoàn thiện một ứng dụng mà tôi muốn ẩn khóa API GoogleMap của mình đằng sau API bảo mật của mình. Ý định của tôi là gọi khóa API sau khi tôi xác minh rằng tôi có một người dùng đã được xác thực. Vấn đề là giữa các cuộc gọi không đồng bộ, các thay đổi không được phản ánh với sự thay đổi trạng thái.
Đây là những gì tôi đang làm:
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;
}
});
}
Nhưng tôi gặp lỗi:
USER_USER_USER null
App.js:78 TypeError: Cannot read property 'signInUserSession' of null
at getGoogleApiKey (App.js:72)
at updateAuth (App.js:42)
Nếu đây là mô hình sai, tôi đánh giá cao bất kỳ lựa chọn thay thế nào!
Trả lời
Khi setUserđược gọi, userbiến vẫn giữ userthông tin cũ ( nulltrong trường hợp này), bất kể async/await:
await checkUser(); // setUser(something) will not happen until next run
await getGoogleApiKey(); // user is still null
await setAuthListener();
Một lựa chọn khác là thêm một hiệu ứng khác khi userthay đổi:
useEffect(() => {
if (user) {
getGoogleApiKey();
}
}, [user]);
Hoặc, gọi getGoogleApiKeyvới tham số:
const user = await checkUser(); // return user
await getGoogleApiKey(user);
await setAuthListener();
Vì logic trở nên phức tạp, tôi khuyên bạn nên thử dùng hook useReducer vì việc điều phối đơn giản hóa các kịch bản qua lại phức tạp này.