无法动态设置自定义 Hook(React)的属性

huangapple go评论140阅读模式
英文:

Cannot set props of custom Hook (React) dynamically

问题

如何使hint属性可变?我希望它可以显示已登录用户的电子邮件。

我尝试通过分配currentUser.email(它是父组件中的状态变量)来实现。这不起作用,因为在登录之前(GoogleLoginButton创建时),该值始终为空。

我尝试使用组件的状态变量,然后在updateUserInContext中设置它。这也不起作用。

我尝试直接在timeout函数的回调中调用useGoogleLogin并传递配置对象。该对象包含了已更新为正确用户电子邮件的hint属性。但是,React会给出编译错误,因为“Hook 只能在函数组件或自定义 Hook 内调用”。

因此,似乎我无法使传递给useGoogleLogin的配置动态化。我使用的依赖是这个:https://github.com/MomenSherif/react-oauth。

如果在同一浏览器会话中只有一个 Google 用户登录,就不需要设置hint属性。如果有两个用户登录,我需要设置它,否则,在后台刷新访问令牌时,应用不知道选择哪个帐户。

你知道是否有办法使hint属性动态化吗?

以下是当前的代码:

export const GoogleLoginButton: React.FC<GoogleLoginButtonProps> = ({ onSuccessfulLogin, onFailedLogin }: GoogleLoginButtonProps) => {

    const { currentUser, setCurrentUser } = useContext(LoginContext)

    const updateUserInContext = async (response: any) => {
        let googleUser = //获取 Google 用户信息的逻辑

        const user = new User()
        user.accessToken = response.access_token
        user.email = googleUser.email
        user.isUserLoggedIn = true
        setCurrentUser(user)

        setTimeout(() => {
            loginWithCurrentUser()
        }, 3 * 1000)
    }

    let loginWithCurrentUser = useGoogleLogin({
        onSuccess: (codeResponse: any) => {
            updateUserInContext(codeResponse)
        },
        onError: (error: any) => {
            console.error(error)
            // 在失败时执行其他操作
        },
        hint: 'user@example.com',
        prompt: 'none'
    })

    const login = useGoogleLogin({
        onSuccess: async codeResponse => {
            updateUserInContext(codeResponse).then(() => {
                // 在成功时执行其他操作
            }).catch(error => {
                // 在失败时执行其他操作
            })
        },
        onError: error => {
            console.log("error")
            // 在失败时执行其他操作
        },
        flow: 'implicit'
    });

    return (
        <div>
            <button onClick={() => login()}>
                Sign in with Google &#128640;{' '}
            </button>
        </div>
    )
}

export interface GoogleLoginButtonProps {
    onSuccessfulLogin: Function,
    onFailedLogin: Function
}
英文:

How can I make the hint prop variable? I want it to have the email of the logged in user.

I tried by assigning currentUser.email (it's a state variable in the parent component). This doesn't work as it's always empty because that value is empty before logging in (when the GoogleLoginButton is created)

I tried with a state variable of the component that I set in the updateUserInContext. It doesn't work.

I tried to call useGoogleLogin directly in the callback of the timeout function and passing the configuration object. This object contains the hint prop updated with the correct user email. Reacts gives me a compilation error because a Hook can be called only inside function components or custom hooks.

So it's seems like I cannot make the configuration I pass to useGoogleLogin dynamic. The dependency I use is this one: https://github.com/MomenSherif/react-oauth.

It's not necessary to set the hint prop if there's only one google user logged in the same browser session.
If there are two users, I need to set it, otherwise, when refreshing the access token in the background, the app doesn't know which account to pick.

Do you know if there's a way to make hint dynamic?

Below the current code

export const GoogleLoginButton: React.FC&lt;GoogleLoginButtonProps&gt; = ({onSuccessfulLogin, onFailedLogin }: GoogleLoginButtonProps) =&gt; {
const {currentUser, setCurrentUser} = useContext(LoginContext)
const updateUserInContext = async (response: any) =&gt; {
let googleUser = //logic to get google user info
const user = new User()
user.accessToken = response.access_token
user.email = googleUser.email
user.isUserLoggedIn = true
setCurrentUser(user)
setTimeout(() =&gt; {
loginWithCurrentUser()
}, 3  * 1000)
} 
let loginWithCurrentUser = useGoogleLogin({
onSuccess: (codeResponse: any) =&gt; {
updateUserInContext(codeResponse)
},
onError: (error:any) =&gt; {
console.error(error)
//Do other things on fail
},
hint: &#39;user@example.com&#39;,
prompt:&#39;none&#39;}
)
const login = useGoogleLogin({
onSuccess: async codeResponse =&gt; {
updateUserInContext(codeResponse).then(() =&gt;{
//Do other things on success
}).catch(error =&gt; {
//Do other things on fail
})
}, 
onError: error =&gt; {
console.log(&quot;error&quot;)
// Do other things on fail
},
flow:&#39;implicit&#39;
});
return (
&lt;div&gt;
&lt;button onClick={() =&gt; login()}&gt;
Sign in with Google &#128640;{&#39; &#39;}
&lt;/button&gt;
&lt;/div&gt;
)
}
export interface GoogleLoginButtonProps {
onSuccessfulLogin: Function,
onFailedLogin: Function
}

答案1

得分: 0

只需在调用 loginWithCurrentUser 时将 hint 作为属性传递,以动态设置它。

setTimeout(() => {
  loginWithCurrentUser({ hint: user.email })
}, 50 * 60 * 1000)
英文:

To set the hint dynamically, just pass it as prop when calling loginWithCurrentUser

setTimeout(() =&gt; {
loginWithCurrentUser({hint: user.email})
}, 50 * 60 * 1000)

huangapple
  • 本文由 发表于 2023年3月9日 20:12:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定