我正在尝试将基于类的组件重构为使用钩子的功能组件。在尝试获取我的登录状态时,我卡在 gapi 中正确使用 useState。
只是为了知道,我想得到什么:
1( 初始化后获取对"auth"对象的引用
2( 确定我当前是否已登录
3( 在屏幕上打印我的身份验证状态
这里已经提出了一个类似的问题:链接,但不幸的是,我错过了将答案实施到我的情况下。
下面是类组件:
import React from "react";
class GoogleAuth extends React.Component {
componentDidMount() {
window.gapi.load("client: auth2", () => {
window.gapi.client
.init({
clientId: "myVerySecretAPI",
scope: "email"
})
.then(() => {
this.auth = window.gapi.auth2.getAuthInstance(); //this gets me acces to the auth object
this.setState({ isSignedIn: this.auth.isSignedIn.get() });
});
});
}
renderAuthButton() {
if (this.state.isSignedIn === null) {
return <div>I dont know if we are signed in</div>;
} else if (this.state.isSignedIn) {
return <div>I am signed in!</div>;
} else {
return <div>I am not signed in</div>;
}
}
render() {
return <div>{this.renderAuthButton()}</div>;
}
}
export default GoogleAuth;
这是我重构的代码:
import React, { useEffect, useState } from "react";
const GoogleAuth = () => {
const [ auth, setAuth ] = useState(null);
useEffect(
() => {
window.gapi.load("client:auth2", () => {
window.gapi.client
.init({
clientId: "834243588921-gob95b7q7n3eids3fm8du8oharkv5od0.apps.googleusercontent.com",
scope: "email"
})
.then(() => {
setAuth(window.gapi.auth2.getAuthInstance());
auth({ isSignedIn: setAuth.isSignedIn.get() }); // this is the line where I get an error (please see below)
});
});
},
[ auth ]
);
const renderAuthButton = (isSignedIn) => {
if (isSignedIn === null) {
return <div>I dont know if we are signed in</div>;
} else if (isSignedIn) {
return <div>I am signed in!</div>;
} else {
return <div>I am not signed in</div>;
}
};
return <div>{renderAuthButton()}</div>;
};
export default GoogleAuth;
我在chrome中得到一个错误,说:
uncatch TypeError: 无法读取 GoogleAuth 上未定义的属性 'get' .js:16
我知道,我缺少一个小东西来理解钩子的使用。 欢迎任何帮助!
所以你基本上保存了几个项目。第一个是您从window.gapi.auth2.getAuthInstance()
获得的实际身份验证实例,第二个是经过身份验证的状态isSignedIn
。在代码中,您setAuth
实例,但随后尝试调用保存的实例并向其传递一些新对象,其中isSignedIn
作为键,状态资源库作为值。这是行不通的。
您可以先获取实例,然后使用该实例从中获取身份验证状态以保存到您的状态中。还应使用空的依赖项数组,以便在挂载GoogleAuth
时仅运行一次效果。
此外,您的renderAuthButton
函数被定义为接受isSignedIn
参数,但您不会在返回中向其传递任何内容。由于这是一个功能组件,但您可以简单地省略参数并在作用域中使用状态值。
const GoogleAuth = () => {
const [isSignedIn, setIsSignedIn ] = useState(null);
useEffect(
() => {
window.gapi.load("client:auth2", () => {
window.gapi.client
.init({
clientId: "834243588921-gob95b7q7n3eids3fm8du8oharkv5od0.apps.googleusercontent.com",
scope: "email"
})
.then(() => {
const authInstance = window.gapi.auth2.getAuthInstance();
setIsSignedIn(authInstance.isSignedIn.get());
});
});
},
[]
);
const renderAuthButton = () => {
if (isSignedIn === null) {
return <div>I don't know if we are signed in</div>;
} else if (isSignedIn) {
return <div>I am signed in!</div>;
} else {
return <div>I am not signed in</div>;
}
};
return <div>{renderAuthButton()}</div>;
};