I have an app where im using React hooks, useState, useEffect, useContext i have 1 page Login.js and loginStoreContext.js file
Login.js im rendering a basic form with a button which has onClick which takes a function exported SigninWithGoogle function
import React,{useContext} from 'react'
import Body from '../../UI/Card/Body';
import {Form } from 'react-bootstrap';
import MainButton from '../../UI/Button/Button';
import {SigninWithGoogleProvider} from '../../store/loginStoreContext'
const Login = () => {
return (
<Body>
<Form>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="[email protected]" />
</Form.Group>
<Form.Group className="mb-3" >
<Form.Label htmlFor="inputPassword5">Password</Form.Label>
<Form.Control
type="password"
id="inputPassword5"
aria-describedby="passwordHelpBlock"
/>
<Form.Text id="passwordHelpBlock" muted>
Your password must be 8-20 characters long, contain letters and numbers,
and must not contain spaces, special characters, or emoji.
</Form.Text>
</Form.Group>
</Form>
<button type="button" onClick={SigninWithGoogleProvider}>Signin with Google</button>
</Body>
)
}
export default Login
SigninWithGoogle.js here im only trying to use google login in my react app
import React , {createContext,useState} from "react";
import app from '../firebaseConfig';
import { GoogleAuthProvider, getAuth, signInWithPopup } from "firebase/auth";
export const AppContext = createContext({
user:{},
token:'',
})
export const SigninWithGoogleProvider = (props)=>{
const [userdata,setUserData] =useState({})
const [token,setToken] = useState('')
const provider = new GoogleAuthProvider();
const auth = getAuth(app)
signInWithPopup(auth,provider)
.then(result=>{
// This gives you a Google Access Token. You can use it to access Google APIs.
const credential = GoogleAuthProvider.credentialFromResult(result);
const userToken = credential.accessToken;
setToken(userToken)
// The signed-in user info.
const user = result.user;
setUserData(user)
})
.catch(error=>{
console.log(error)
})
return <AppContext.Provider value={{
user:userdata,
token:token
}}>
{props.children}
</AppContext.Provider>
}
After research i came to know i cant use hooks inside event if i comment useState the code will work but i need to manage the state in context so i can access my Auth user at any where is there a work solution would help on this?
i tried to research on the issues after researching i came to know that i cant use useState with events but i need the to have them like this to manage my state i cant keep it inside the component
2
Answers
HI all i saw pilchard's comment and after trying i can now add it to my state what i did is i added a function in SigninWithGoogleProvider before i wasnt access it via a function but directly via a provider which is wrong and has to be a function which then will return a state.
sample on what i did:
SigninWithGoogle.js
}) export const SigninWithGoogleProvider = (props)=>{
}
Login.js
From what you have written, it seems the
Context
is not needed, you just need to pass data from the parent component to the child, as well as a change callback.This is a semplification of your code, but I think it’s enough for you to understand. Let me know if you don’t understand something or you want a deeper answer.
What I’ve done here is "Lifting the state up", as suggested in REACT documentation: https://react.dev/learn/sharing-state-between-components#lifting-state-up-by-example
Basically, you are saving the data in the parent component, and you pass the data to the child. Also, you pass to the child a callback that allows to update the state of the parent.