hy i begin in react and i try to get user data from my api with my cookie, i have the data but when i console.log() the user data i have 4 undefined and then 2 same object data. The problem is i don't know why and when i try to get user.id in an other components using props i have tpyerror id undefined.
import React, {useState, useEffect} from "react";
import NavBar from "./component/NavBar";
import Navigation from "./component/Navigation"
import Cookie from "js-cookie"
import axios from "axios"
import "./App.css";
function App() {
const [user, setUser] = useState()
const [logged, setLogged] = useState(false)
const cookie = Cookie.get("login")
useEffect(() => {
axios.post('/getdatafromcookie', cookie)
.then((res) => {
if(res.data.success === true){
setLogged(true)
setUser(res.data.user)
}
})
}, [])
console.log(user)
return (
<div className="App">
<header className="NavHeader">
<NavBar user={user} logged={logged} />
</header>
<Navigation user={user} logged={logged}/>
</div>
);
}
export default App;
And the console log shows me:
Navbar
import React, { useState, useEffect } from "react";
import RegisterForm from "../component/RegisterForm";
import RegisterLogin from "../component/RegisterLogin";
import { Navbar, Nav, Dropdown } from "react-bootstrap";
import { Button } from "@material-ui/core"
export default function NavBar(props) {
const [modalLoginShow, setModalLoginShow] = useState();
const [modalRegisterShow, setModalRegisterShow] = useState();
const user = props.user
const islogged = props.logged
if(islogged === false)
{
return (
<Navbar collapseOnSelect expand="lg" bg="transparent" variant="light">
<Navbar.Brand href="/">Matchandate</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto"></Nav>
<Nav>
<Nav.Link onClick={() => setModalLoginShow(true)}>
<Button variant="contained" color="secondary">Login</Button>
</Nav.Link>
<Nav.Link onClick={() => setModalRegisterShow(true)}>
<Button variant="contained" color="secondary" >Register</Button>
</Nav.Link>
</Nav>
</Navbar.Collapse>
<RegisterLogin show={modalLoginShow} onHide={() => setModalLoginShow(false)} />
<RegisterForm show={modalRegisterShow} onHide={() => setModalRegisterShow(false)} />
</Navbar>
)
}
return(
<Navbar collapseOnSelect expand="lg" bg="transparent" variant="light">
<Navbar.Brand href="/">Matchandate</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto"></Nav>
<Nav>
<Nav.Link href="/profile">
<Button variant="contained" color="primary">Profile</Button>
</Nav.Link>
<Nav.Link href="/logout">
<Button variant="contained" color="primary" >Logout</Button>
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
Navigation
import React from "react"
import Slider from "./SliderHome";
import Activate from "./Activate";
import ForgotPwd from "./Pages/ForgotPwd"
import ChangePwd from "./Pages/ChangePwd"
import UserProfile from "./Pages/UserProfil";
import ErrorPage from "./Pages/ErrorPage"
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
export default function Navigation(props){
const user = props.user
const islogged = props.logged
if(islogged){
return(
<Router>
<Switch>
<Route exact path="/" exact component={Slider} />
<Route exact path="/profile" component={() => <UserProfile user={user} />} />
{/* <Route path="/user/:id" component={ChangePwd}/> */}
<Route path="/" component={ErrorPage} />
</Switch>
</Router>
)
}
return (
<Router>
<Switch>
<Route exact path="/" exact component={Slider} />
<Route path="/activate" component={Activate} />
<Route path="/forgot-pwd" component={ForgotPwd}/>
<Route path="/changepwd" component={ChangePwd}/>
{/* <Route path="/user/:id" component={ChangePwd}/> */}
<Route path="/" component={ErrorPage} />
</Switch>
</Router>
)
}
This happens because useEffect is executed after the first render, so, the first time user is null, you will need to guard your code to render once you have data inside user
return user ? <div className=“app”><NavBar user={user}/></div> : <div>loading</div>)
The logs being printed so many times is because strict mode in development
In yours first render: your user is undefined it's normal because your are not defined a default value in your usestate you can change your code by this const [user, setUser] = useState({})
or this
import React, {useState, useEffect} from "react";
import NavBar from "./component/NavBar";
import Navigation from "./component/Navigation"
import Cookie from "js-cookie"
import axios from "axios"
import "./App.css";
function App() {
const [user, setUser] = useState()
const [logged, setLogged] = useState(false)
const cookie = Cookie.get("login")
useEffect(() => {
axios.post('/getdatafromcookie', cookie)
.then((res) => {
if(res.data.success === true){
setLogged(true)
setUser(res.data.user)
}
})
}, [])
console.log(user)
return (
<div className="App">
<header className="NavHeader">
{user ? <NavBar user={user} logged={logged} /> : "loading"}
</header>
{user ? <Navigation user={user} logged={logged}: "loading" />
</div>
);
}
export default App;
The problem is i don't know why and when i try to get user.id in an other components using props i have tpyerror id undefined.
The reason for that is that you try to get the id of the user before the user is loaded , which means you're doing something like null.id
which is undefined (depends on what useState
returns when called without any arguments, probably null)
The reason you get multiple Undefined in console.log
is:
the first time your App
component is rendered, useEffect
didn't finish calling the api yet, so user
is still undefined
, the 2nd time is because you called setLogged(true)
so user is still undefined
, the 3rd and 4th times... i'm not sure, but you're probably changing the state somehow which causes a re-render
the proper wait to fix this, would be to wait until user
is defined
(ie the api call is finished), you can do that by using a simple if
statement, something like
if (user.id) {
// return components when the user is logged in
} else {
// return components where the user is not logged in, usually a "loading" screen
}
Now you said user.id
returns type error
but i couldn't find any user.id
in your code, so i assumed that you didn't post the whole thing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.