1

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')

1 Answer 1

2

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}/> }/>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.