1
resposta

AuthContext usando React e Typescript

Boa noite, preciso muito de uma ajuda aqui. Estou criando um AuthContext e estou me deparando com os seguintes erros, como poderia resolver?

type User = {
  email: string;
}

type Signup = {
  email: string;
  password: string;
}

type AuthContextProviderProps = {
  children?: ReactNode | undefined;
}

type AuthContextType = {
  user: User | undefined;
  signIn: (props: Signup) => void;
  signUp: () => void;
}


export const AuthContext = createContext({} as AuthContextType);


export function AuthContextProvider(props: AuthContextProviderProps){

  function signUp(props: Signup) {
    return createUserWithEmailAndPassword(auth, props.email, props.password)
  }
  function signIn(props: Signup) {
    return signInWithEmailAndPassword(auth, props.email, props.password)
  }

  useEffect(() => {
    const [user, setUser] = useState<User>();
    const unsubscribe = auth.onAuthStateChanged(user => {
      if (user) {
        const { email } = user

        if (!email) {
          throw new Error('Missing information from your Account.');
        }
        setUser({
          email: email
        })
      }
    })

    return () => {
      unsubscribe();
    }
  }, [])


  const value = {
    signIn,
    signUp

  }

  return (
    <AuthContext.Provider  value={ value }>
      {props.children}
    </AuthContext.Provider>
  )

}

erros:

A propriedade 'user' está ausente no tipo '{ signIn: (props: Signup) => Promise; signUp: (props: Signup) => Promise; }', mas é obrigatória no tipo 'AuthContextType'.ts(2741) AuthContext.tsx(20, 3): 'user' é declarado aqui. index.d.ts(338, 9): O tipo esperado vem da propriedade 'value', que é declarada aqui no tipo 'IntrinsicAttributes & ProviderProps'

o erro está na linha : ** <AuthContext.Provider value={ value }>**

Socorro!!! Deve ser um erro de sintaxe acredito

1 resposta

Olá, Érica!

Tem alguns ajustes que acho que você precisa fazer. Primeiro, aqui:

  useEffect(() => {
    const [user, setUser] = useState<User>();
    const unsubscribe = auth.onAuthStateChanged(user => {
      if (user) {
        const { email } = user

        if (!email) {
          throw new Error('Missing information from your Account.');
        }
        setUser({
          email: email
        })
      }
    })

    return () => {
      unsubscribe();
    }
  }, [])

Não podemos usar hooks dentro de hooks dessa forma, logo o const [user, setUser] = useState<User>(); precisa ficar fora do useEffect, assim:

  const [user, setUser] = useState<User>();
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(user => {
      if (user) {
        const { email } = user

        if (!email) {
          throw new Error('Missing information from your Account.');
        }
        setUser({
          email: email
        })
      }
    })

    return () => {
      unsubscribe();
    }
  }, [])

Já no seu value, o ponto é que ele espera um user além do signIn e do signUp:

  const value = {
    signIn,
    signUp,
    user
  }

Ao fazer isso, o TypeScript vai reclamar do signUp.

No seu type, você definiu que ele não recebe parametros:

type AuthContextType = {
  user: User | undefined;
  signIn: (props: Signup) => void;
  signUp: () => void;
}

Mas no método, você precisa deles:

  function signUp(props: Signup) {
    return createUserWithEmailAndPassword(auth, props.email, props.password)
  }

Então acho que a versão final seria algo mais ou menos assim:

type User = {
  email: string;
}

type Signup = {
  email: string;
  password: string;
}

type AuthContextProviderProps = {
  children?: ReactNode | undefined;
}

type AuthContextType = {
  user: User | undefined;
  signIn: (props: Signup) => void;
  signUp: () => void;
}


export const AuthContext = createContext({} as AuthContextType);


export function AuthContextProvider(props: AuthContextProviderProps){

  function signUp(props: Signup) {
    return createUserWithEmailAndPassword(auth, props.email, props.password)
  }
  function signIn(props: Signup) {
    return signInWithEmailAndPassword(auth, props.email, props.password)
  }

  const [user, setUser] = useState<User>();
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(user => {
      if (user) {
        const { email } = user

        if (!email) {
          throw new Error('Missing information from your Account.');
        }
        setUser({
          email: email
        })
      }
    })

    return () => {
      unsubscribe();
    }
  }, [])


  const value = {
    signIn,
    signUp,
    user

  }

  return (
    <AuthContext.Provider  value={ value }>
      {props.children}
    </AuthContext.Provider>
  )

}