useContext - 应用程序文件中未定义用户ID

问题描述 投票:0回答:1

我有一个问题。我想访问 app.tsx 文件中的用户 ID,但问题是 AuthContextProvider 文件中的 userID 具有取决于登录用户的值,但在 app.tsx 文件中该值仍然未定义。

我该如何解决我的问题?

App.tsx:

import "./shared/styles/crema.less";
import {
  AppContextProvider,
  AppLayout,
  AppLocaleProvider,
  AppThemeProvider,
  AuthRoutes,
} from "./domain";
import { BrowserRouter } from "react-router-dom";
import AuthContextProvider, { AuthContext } from "./pages/auth/context";
import { QueryClient, QueryClientProvider } from "react-query";
import { useContext, useEffect, useState } from "react";
import { Socket, io } from "socket.io-client";
import { func } from "prop-types";
const queryClient = new QueryClient();

export const newSocket: any = io("http://151.248.117.169:3001");

const App = () => {
  const authContext = useContext(AuthContext);
  console.log('userId: ', authContext, { authContext })
  const [socket, setSocket] = useState<any>();

  useEffect(() => {
    newSocket.connect();
    console.log("socket: ", newSocket)
    setSocket(newSocket);

    return () => {
      newSocket.disconnect();
    };
  }, []);


  useEffect(() => {
    socket?.emit('addNewAccount', {
      "id": 2,
      "type": 1,
    }, (val: any) => {
      console.log(val);
    });
  }, [socket]);

  return (
    <AppContextProvider>
      <AuthContextProvider>
        <QueryClientProvider client={queryClient}>
          <AppThemeProvider>
            <AppLocaleProvider>
              <BrowserRouter>
                <AuthRoutes>
                  <AppLayout />
                </AuthRoutes>
              </BrowserRouter>
            </AppLocaleProvider>
          </AppThemeProvider>
        </QueryClientProvider>
      </AuthContextProvider>
    </AppContextProvider>
  );
};

export default App;

AuthContextProvider.tsx:

import React, { createContext, useState, useEffect, ReactElement } from "react";
import { AuthContextProps } from "./types";
import { useCookies } from "react-cookie";
import { ILoginDto } from "../../../shared/services/auth/dtos/login-dto";
import {
  AUTH_TOKEN,
  EXHIBITOR_LOGO,
  EXHIBITOR_NAME,
  EXHIBITOR_STAND_DESIGN,
} from "../../../shared/constants/AppConst";
import { authService } from "../../../shared/services/auth";
import MainUtils from "../../../shared/utils/main";
import { notifier } from "../../../shared/functions/notifier";
import { Navigate, useNavigate, useParams, useRoutes } from "react-router-dom";
export const AuthContext = createContext<AuthContextProps>({});

const AuthContextProvider = ({ children }: { children: ReactElement<any, any> }) => {
  const [authenticated, setAuthenticated] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [visibleLogout, setVisibleLogout] = useState<boolean>(false);
  const [responseError, setError] = useState<any>("");
  const [cookies, setCookies, removeCookies] = useCookies([AUTH_TOKEN]);
  const [cookiesEmail] = useCookies(["email"]);
  const [userId, setUserId] = useState<any>();

  const logout = async () => {
    setLoading(true);
    await authService.logout().then(async (response: any) => { });
    removeCookies(AUTH_TOKEN);
    removeCookies(EXHIBITOR_NAME);
    setVisibleLogout(false);
    setLoading(false);
  };

  const login = async (values: any) => {
    setLoading(true);

    let request: ILoginDto = {
      email: values?.email,
      password: values?.password,
      fcm_token: values.fcm_token,
    };
    await authService
      .login(request)
      .then((response: any) => {
        setUserId(response?.data?.id);
        if (!MainUtils.isEmptyValue(response?.errors)) {
          response?.errors?.map((error: string) => {
            notifier(error, "error");
          });
        }
        if (response?.data?.token) {
          setCookies(AUTH_TOKEN, `${response?.data?.token}`, {
            path: "/",
            sameSite: true,
          });
          setCookies(EXHIBITOR_NAME, `${response?.data?.name}`, {
            path: "/",
            sameSite: true,
          });
          setCookies(EXHIBITOR_LOGO, `${response?.data?.logo}`, {
            path: "/",
            sameSite: true,
          });
          setCookies(
            EXHIBITOR_STAND_DESIGN,
            `${response?.data?.stand_design}`,
            {
              path: "/",
              sameSite: true,
            }
          );
        }
      })
      .catch(({ response }) => {
        const errorMessage: string =
          response?.data?.errors?.[
          Object.keys(response?.data?.errors)[0]
          ]?.[0] || "Something went wrong, try again later!";
        notifier(errorMessage, "error");
      });
    setLoading(false);
  };


  const recoverPassword = async (values: any) => {
    setLoading(true);
    await authService
      .resetPassword({ ...values, email: cookiesEmail["email"] })
      .then((response: any) => {
        if (response?.error) {
          setError(response?.error?.message);
        }
        if (response?.data) {
          setError("");
          window.location.href = "/sign-in";
        }
      });
    setLoading(false);
  };

  const resendCode = async (values: any) => {
    setLoading(true);
    await authService.resendCode({ ...values }).then((response: any) => {
      if (response?.error) {
        setError(response?.error?.message);
      }

      if (response) {
        setError("");
        window.location.replace("/confirm-code");
      }
    });
    setLoading(false);
  };

  const confirmCode = async (values: any) => {
    setLoading(true);
    await authService.confirmCode({ ...values }).then((response: any) => {
      if (response?.error) {
        setError(response?.error?.message);
      }
      setCookies("email", `${values?.email}`, {
        path: "/",
        sameSite: true,
      });
      if (response?.data) {
        setError("");
        <Navigate to={"forget-password"} replace />;
      }
    });
    setLoading(false);
  };

  return (
    <AuthContext.Provider
      value={{
        responseError: responseError,
        loading: loading,
        visibleLogout: visibleLogout,
        setVisibleLogout: setVisibleLogout,
        logout: logout,
        login: login,
        recoverPassword: recoverPassword,
        isAuthenticated: authenticated,
        setAuthenticated: setAuthenticated,
        confirmCode: confirmCode,
        userId: userId,
        resendCode,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

export default AuthContextProvider;
reactjs react-context
1个回答
0
投票

AuthContextProvider
将提供值并访问组件中的值,您必须将提供程序包装在安装组件的位置,例如:
app.tsx

此处您尝试访问

AuthContext
中的
app.tsx
值。但是
App
组件没有被
AuthContextProvider
包裹。如果您想访问
index.js
中的上下文值,我建议您将此提供程序移至
App
并将其包装到
App.tsx
组件。

如下:

import {AppContextProvider} from '../domain';

ReactDOM.createRoot(document.getElementById('root')).render(
    <AuthContextProvider>
        <App />
    </AuthContextProvider>
)
© www.soinside.com 2019 - 2024. All rights reserved.