【问题标题】:how to execute a component before another one in next.js?在 next.js 中如何在另一个组件之前执行一个组件?
【发布时间】:2023-01-12 17:46:44
【问题描述】:

我一直在努力解决这个问题。我有一个 Auth 组件,我在其中尝试访问本地存储以查看其中是否有令牌并将其发送到服务器以验证该令牌。 如果令牌有效,用户将自动登录。

//     ./components >> Auth.tsx

const Auth : React.FC<Props> = ({children}) => { 

    const dispatch = useDispatch() // I'm using redux-toolkit to mange the app-wide state

    useEffect(() => {
        if (typeof window !== 'undefined') {
            const token = localStorage.getItem("token")
            const userId = localStorage.getItem("userId")
            if (userId) {
                axios.post("/api/get-user-data", {userId, token}).then(res => {
                        dispatch(userActions.login(res.data.user))  // the user gets logged-in
                    }
                ).catch(error => {
                        localStorage.clear()
                        console.log(error)
                    }
                )
            }
        }

    }, [dispatch])


    return (
        <Fragment>
            {children}
        </Fragment>
    )
}

export default Auth

然后我用 Auth.tsx 将每个页面组件包装在 _app.tsx 文件中,以便全局管理身份验证状态。

//  .pages >> _app.tsx

            <Provider store={store}>
                        <Auth>
                            <Component {...pageProps} />
                        </Auth>
            </Provider>

我有一个用户个人资料页面,用户可以在其中查看他/她的所有信息。 在此页面中,首先我检查用户是否已通过身份验证以访问此页面。 如果不是,我将他重定向到登录页面

// ./pages >> user-profile.tsx

useEffect(() => {
        if (isAuthenticated) {
           // some code
        } else {
            router.push("/sign-in")

        }
    }, [isAuthenticated])

问题是当用户在用户配置文件页面并重新加载时。那么即使用户通过了身份验证,用户也总是会被重定向到登录页面。

这是因为 user-profile useEffect 中的代码在 Auth 组件中的代码之前执行。 (用户配置文件页面是 Auth 组件的子组件)

我应该如何在用户配置文件页面中的代码之前运行 Auth 组件中的代码?

我想让用户仅在他未通过身份验证时重定向,并在任何其他代码之前运行所有与身份验证相关的代码。

【问题讨论】:

    标签: reactjs authentication react-hooks next.js frontend


    【解决方案1】:

    您确定问题是用户配置文件的useEffect 在 Auth 的useEffect 之前执行了吗?我会假设最外面的useEffect 首先被解雇。

    在您的情况下最有可能发生的是您在 Auth useEffect 中运行的代码是异步的。你用 Axios 向你的 API 发送请求,然后 useEffect 方法继续运行而不等待结果。通常情况下,这是一个很好的情况,但在您的配置文件中,您假设您已经有了这次调用的结果。

    您可能必须实现 async 函数和 await axios.post 方法和 dispatch 方法的结果。你需要这样的东西:

    useEffect(() => {
       async () => {
           if (typeof window !== 'undefined') {
               const token = localStorage.getItem("token")
               const userId = localStorage.getItem("userId")
               if (userId) {
                   try {
                       const resp = await axios.post("/api/get-user-data", {userId, token})
                       await dispatch(userActions.login(res.data.user))  // the user gets logged-in
                   } catch(error) {
                       localStorage.clear()
                       console.log(error)
                   }
               }
           }
       }()
    }, [dispatch])
    

    我认为这应该可行,但它会导致您的组件在呈现任何内容之前等待响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2011-03-19
      • 1970-01-01
      • 2020-09-04
      • 2010-11-30
      • 2021-12-04
      • 1970-01-01
      相关资源
      最近更新 更多