Reputation: 185
I have to pass my state from Authentication.js to App.js, to make certain functionalities available to registered users.
This is my file Authentication.js
import { useState } from "react"
import MyButton from "../componens/myButton"
import styles from "../style/authentication.module.css"
import Spinner from "../componens/Spinner"
import axios from "axios"
const Authentication = () =>{
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [loading, setLoading] = useState(false)
const [registration, setRegistration] = useState(true)
const [state, setState] = useState(null)
let MyRegistration = null;
const handleSubmit = async (e) =>{
e.preventDefault()
setLoading(true)
try {
const userKey = `AIzaSyCYe1XVuJVflRie0sf1y01RNrmQ77Dmp4Q`
let urlAPI = `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${userKey}`
if (!registration) {
urlAPI = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${userKey}`
}
setEmail(email);
setPassword(password);
MyRegistration = await axios.post(urlAPI,{
email : email,
password : password,
returnSecureToken : true
})
setState(MyRegistration)
setLoading(false);
return MyRegistration
} catch (error) {
setLoading(false)
console.log(error)
}
}
return <div className={styles.formContainer}>
<h1>Authentication</h1>
<form onSubmit={handleSubmit} action="">
<p>Email</p>
<input placeholder="Your email" type="email" value={email} onChange={handleEmail} />
<p>Password</p>
<input placeholder="Your Password" type="password" value={password} onChange={handlePassword} />
{loading ? <Spinner/> :
<MyButton title={registration ? 'sign up' : 'Sign in'} handleClickButton={handleSubmit} />}
<MyButton title={registration ? 'Go to Sign in' : 'Go to sign up'} handleClickButton={changeMode}/>
</form>
</div>
}
export default Authentication;
This is my file App.js
import Home from './pages/Home';
import Book from './pages/Book'
import {Route, Switch} from 'react-router-dom';
import SavedBooks from './pages/SavedBooks';
import Header from './componens/Header';
import BookChapter from './pages/BookChapter';
import Authentication from './pages/Authentication';
import {useState} from "react";
function App(props) {
const [userData, setUserData] = useState("");
return (
<div>
<Header/>
<Switch>
<Route exact path="/" render={(props) => <Home userData={userData}/>}/>
<Route exact path="/book/:id" component={Book}/>
<Route exact path="/savedbooks" component={SavedBooks}/>
<Route exact path="/book/:id/chapter/:numero" component={BookChapter}/>
<Route exact path="/authentication" render={(props) => <Authentication setUserData={setUserData(this.state)}/> }/>
</Switch>
</div>
)
}
export default App;
But the response is: TypeError: Cannot read properties of undefined (reading 'state')
Upvotes: 1
Views: 1248
Reputation: 104
You cannot pass the state declared in Authentication.js
to its parent App.js
. So, you need to make a useState in App.js
and pass the state and its corresponding setterFunction onto the child i.e Authentication.js
. This is known as lifting up the state.
Move const [state, setState] = useState(null)
to App.js
and use the state
variable in App.js and pass it onto child like this
<Route exact path="/authentication" render={(props) => <Authentication state={state} setState={setState}/> }/>
Upvotes: 2