【问题标题】:React Mulitple rendering functional componentReact 多重渲染功能组件
【发布时间】:2020-07-12 17:00:39
【问题描述】:

我开始做出反应,我尝试使用我的 cookie 从我的 api 获取用户数据,我有数据,但是当我 console.log() 时,我有 4 个未定义的用户数据,然后是 2 个相同的对象数据。问题是我不知道为什么以及当我尝试使用道具在其他组件中获取 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;

控制台日志显示:

  • 未定义
  • 未定义
  • 未定义
  • 未定义
  • {id:“31”,电子邮件:“test@test.fr”等.....}
  • {id:“31”,电子邮件:“test@test.fr”等.....}

导航栏

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

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    问题是我不知道为什么,当我尝试使用道具在其他组件中获取 user.id 时,我的 tpyerror id 未定义。

    这样做的原因是您尝试在加载用户之前获取用户的 id,这意味着您正在执行类似 null.id 的未定义的操作(取决于 @ 987654322@不带任何参数调用时返回,可能为null)

    console.log 中出现多个 Undefined 的原因是:

    你的App组件第一次渲染,useEffect还没调用完api,所以user还是undefined,第二次是因为你调用了setLogged(true)所以用户还在undefined,第 3 次和第 4 次...我不确定,但您可能正在以某种方式更改状态,导致重新渲染

    解决此问题的正确等待是等到userdefined(即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,所以我认为你没有发布整个内容。

    【讨论】:

    • 在 /profile 路由的导航组件上,我调用 UserProfile 组件,我尝试在其中打印 id 用户,它工作得很好,所以谢谢 :)
    【解决方案2】:

    这是因为 useEffect 是在第一次渲染后执行的,所以,第一次 user 为 null 时,你需要保护你的代码在用户内部有数据后渲染

    return user ? <div className=“app”><NavBar user={user}/></div> : <div>loading</div>)
    

    日志被打印这么多次是因为开发中的严格模式

    【讨论】:

      【解决方案3】:

      在您的第一次渲染中:您的用户未定义这是正常的,因为您未在使用状态中定义默认值,您可以通过此 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;
      

      【讨论】:

        猜你喜欢
        • 2020-01-06
        • 2022-11-29
        • 2021-02-14
        • 2021-01-19
        • 2018-02-17
        • 2021-08-23
        • 2021-09-29
        • 1970-01-01
        • 2019-03-24
        相关资源
        最近更新 更多