[英]React Mulitple rendering functional component
我开始反应,我尝试使用我的 cookie 从我的 api 获取用户数据,我有数据,但是当我 console.log() 用户数据时,我有 4 个未定义的用户数据,然后是 2 个相同的 object 数据。 问题是我不知道为什么以及当我尝试使用道具在其他组件中获取 user.id 时,我的 tpyerror id 未定义。
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;
控制台日志显示:
导航栏
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>
)
}
导航
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>
)
}
发生这种情况是因为 useEffect 在第一次渲染后执行,因此,第一次用户是 null,一旦用户内部有数据,您将需要保护代码以进行渲染
return user ? <div className=“app”><NavBar user={user}/></div> : <div>loading</div>)
日志被打印这么多次是因为开发中的严格模式
在你的第一次渲染中:你的用户是未定义的,这是正常的,因为你没有在你的 usestate 中定义一个默认值你可以通过这个const [user, setUser] = useState({})
或者这个来改变你的代码
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;
问题是我不知道为什么以及当我尝试使用道具在其他组件中获取 user.id 时,我的 tpyerror id 未定义。
原因是您尝试在加载用户之前获取用户的 id,这意味着您正在执行类似null.id
类的未定义的操作(取决于在没有任何 arguments 的情况下调用时useState
返回的内容,可能为空)
您在console.log
中获得多个 Undefined 的原因是:
第一次渲染App
组件时, useEffect
还没有完成调用 api ,所以user
仍然是undefined
,第二次是因为你调用setLogged(true)
所以 user 仍然是undefined
,第三次和第四次......我不确定,但您可能正在以某种方式更改 state 导致重新渲染
解决此问题的正确等待是等到defined
user
(即 api 调用完成),您可以使用简单的if
语句来做到这一点,例如
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
}
现在您说user.id
返回type error
,但我在您的代码中找不到任何user.id
,所以我假设您没有发布整个内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.