Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
121 views
in Technique[技术] by (71.8m points)

javascript - Why my pure functional component is rendering differently?

I'm trying to fix a design issue, where in a certain case, the classes declared in a <div className="XXXX"></div>are not attached the the div in the dom.

This happen when i directly hit the endpoint /dashboard of my Next.JS website but not when I use router.push('/dashboard') of next/router (when i'm on /)

My project is organised like this:

├── components
│   ├── Dashboard
│   │   ├── Dashboard.jsx
│   │   └── UnAuthorized.jsx
│   ├── Emoji.jsx
│   ├── Landing
│   │   ├── AskRecoveryModal.jsx
│   │   ├── index.jsx
│   │   ├── RecoveryModal.jsx
│   │   ├── SignIn.jsx
│   │   └── SignUp.jsx
│   └── Layout
│       ├── Footer.jsx
│       └── index.jsx
├── package.json
├── package-lock.json
├── pages
│   ├── api
│   │   └── hello.js
│   ├── _app.js
│   ├── dashboard.js
│   └── index.js
├── postcss.config.js
├── public
│   ├── cryptopolitain-logo.png
│   ├── favicon.ico
│   └── vercel.svg
├── README.md
├── styles
│   ├── globals.css
│   └── Home.module.css
└── tailwind.config.js

The index.js:

import Layout from "../components/Layout"
import Landing from "../components/Landing/"


export default function Home() {
  return (
      <Layout>
          <Landing />
      </Layout>
  )
}

The SignIn.jsx (which is imported in ):

import { useRouter } from 'next/router'
import { useEffect, useRef, useState } from 'react'
import { Button, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, TextField } from '@material-ui/core'
import { Spinner } from 'bumbag'
import { useIdentityContext } from 'react-netlify-identity'
import AskRecoveryModal from './AskRecoveryModal'

export default function SignUpButton () {

    const formRef = useRef()
    const router = useRouter()
    const { loginUser } = useIdentityContext()
    
    useEffect(() => {

    })
    const [open, setOpen] = useState(false)
    const handleOpen = () => setOpen(true)
    const handleClose = () => {
        setOpen(false)
        document.getElementById("connection-form").reset()
        setMsg("")
    }
    const initialState = {
        errorPassword: false,
        errorPasswordtext: "",
        errorEmail: false,
        errorEmailText: ""
    }
    const [state, setState] = useState(initialState)
    const [waitForResponse, setWaitForResponse] = useState(false)
    const [msg, setMsg] = useState("")

    const signIn = () => {
        setWaitForResponse(true)
        const email = formRef.current.email.value
        const password = formRef.current.password.value
        loginUser(email, password, true)
          .then(user => {
            setWaitForResponse(false)
            console.log('Success! Logged in', user)
            router.push('/dashboard')
          })
          .catch(err => {
            setWaitForResponse(false)
            console.error(err)
            setMsg("Combinaison incorrecte, as-tu vérifié ton email ?")
        })
    }

    const handleKeyDown = (e) => {
        if (e.key === 'Enter') {
          signIn()
        }
      }

    const [openRecoveryModal, setOpenRecoveryModal] = useState(false)
    const closeRecoveryModal = () => setOpenRecoveryModal(false)
    const askRecovery = () => {
        setOpen(false)
        setOpenRecoveryModal(true)
    }

    return (
        <div>
            <Button variant="contained" color="primary" size="large" onClick={() => handleOpen()}>Connexion</Button>
            <Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
                <DialogTitle id="form-dialog-title"><div className="text-2xl">Se connecter</div></DialogTitle>
                <DialogContent>
                <div className="md:w-80">
                    <DialogContentText style={{ fontSize: `0.9rem` }}>
                        Connectez-vous pour acceder au dashboard
                        {msg !== "" && <div className="text-red-600"><br />{msg}</div>}
                    </DialogContentText>
                </div>
                    <form ref={formRef} id="connection-form">
                        <div className="mt-3">
                            <TextField
                                autoFocus
                                error={state.errorEmail}
                                helperText={state.errorEmailText}
                                name="email"
                                label="Email"
                                type="email"
                                fullWidth
                                autoComplete="email"
                                onKeyDown={(e) => handleKeyDown(e)}
                            /></div>
                        <div className="mt-3">
                            <TextField
                                error={state.errorPassword}
                                helperText={state.errorPasswordText}
                                name="password"
                                label="Mot de passe"
                                type="password"
                                fullWidth
                                autoComplete="password"
                                onKeyDown={(e) => handleKeyDown(e)}
                            />
                        </div>
                    </form>
                    {msg !== "" && <button onClick={() => askRecovery()} className="text-xs mt-3 text-red-700 hover:text-red-500">Mot de passe oublié ?</button>}
                </DialogContent>
                <DialogActions>
                    <Button onClick={() => handleClose()} >
                        Annuler
                    </Button>
                    <Button onClick={() => signIn()} color="primary" variant="contained">
                        {waitForResponse ? <Spinner /> : `Se connecter`}
                    </Button>
                </DialogActions>
            </Dialog>
            <AskRecoveryModal open={openRecoveryModal} handleClose={() => closeRecoveryModal()}  />
        </div>
    )
}

The Dashboard.jsx component is:

import Layout from '../Layout'
import Emoji from '../Emoji'
import { useIdentityContext } from 'react-netlify-identity'
import { useRouter } from 'next/router'
import { Button } from '@material-ui/core'

export default function Dashboard() {
    const { logoutUser } = useIdentityContext();
    const router = useRouter()
    const logout = () => {
        logoutUser()
        router.push('/')
    }
    return (
        <div className="w-full h-full flex flex-col justify-center items-center"> {* THE ISSUE IS HERE *}
            <div className="mb-12 text-xl">Dashboard en construction... <Emoji symbol="??" label="construction"/></div>
            <Button variant="outlined" color="primary" size="large" onClick={() => logout()}>Se déconnecter</Button>
        </div>
    )
}

and is called by pages/dashboard.js which is:

import { useIdentityContext } from 'react-netlify-identity'
import Dashboard from '../components/Dashboard/Dashboard'
import UnAuthorized from '../components/Dashboard/UnAuthorized'
import Layout from '../components/Layout'

export default function DashboardRoute () {

    const identity = useIdentityContext()

    return (
        <Layout>
            {identity.user ? <Dashboard /> : <UnAuthorized />}
        </Layout>
    )
}

I tried to go on the Profiler section of the React Dev Tools, but there is absolutely 0 difference between the render tree of the two cases.

But in fact when I go directly to /dashboard the div on the real DOM don't have his classes. (but his child <div className="mb-12 text-xl"> is good.

And when I use router.push('/dashboard')from / the div on the real DOM have his classes.

I hope to have been clear, I can give more information if needed.

Thanks you !


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...