获取导致 React 闪烁的输入值
Getting value of input causing flickering in React
我试图通过获取更改时的值并将此值存储在本地状态中来跟踪两个登录输入字段的值,这样当用户提交登录时,我就可以从状态中获取当前值.但是,这会导致输入在我输入文本时闪烁,并且在我输入密码字段时也会出现奇怪的故障(光标跳回电子邮件字段)。可以在下面观察到故障(请注意,我没有按 shift-tab 键返回电子邮件字段,当我输入密码字段时,它似乎由于某种原因自动发生)。
以下是我的 profile_tile.js
的代码,我将其作为嵌套在导航栏中的组件:
import React, { useState } from 'react'
import { useFirebase, isLoaded, isEmpty } from 'react-redux-firebase'
import { useSelector } from 'react-redux'
import Modal from '../../modal'
export default function ProfileTile() {
const firebase = useFirebase()
const auth = useSelector(state => state.firebase.auth)
const profile = useSelector(state => state.firebase.profile)
const [showLoginModal, setLoginModalShow] = useState(false)
const [showSignupModal, setSignupModalShow] = useState(false)
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const createNewUser = () => {
firebase.createUser({ email, password })
setLoginModalShow(false)
setSignupModalShow(false)
}
const handleEmailChange = event => {
setEmail(event.target.value)
console.log('EMAIL' + event.target.value)
}
const handlePasswordChange = event => {
setPassword(event.target.value)
console.log('PASSWORD' + event.target.value)
}
const logout = () => {
firebase.logout()
}
const handleLoginModalShow = () => {
setLoginModalShow(true)
setSignupModalShow(false)
}
const handleLoginModalHide = () => {
setLoginModalShow(false)
}
const handleSignupModalShow = () => {
setLoginModalShow(false)
setSignupModalShow(true)
}
const handleSignupModalHide = () => {
setSignupModalShow(false)
}
const handleLogin = () => {
firebase.login({ email: email, password: password })
setLoginModalShow(false)
setSignupModalShow(false)
}
const loginModal = showLoginModal ? (
<Modal>
<div class='vh-100 dt w-100 bg-black-80 overlay fixed z-999'>
<div class='v-mid dtc tc center '>
<article class='mw6 center br2 bg-white ba b--black-10'>
<svg
viewBox='0 0 12 12'
height='20'
width='20'
version='1.1'
onClick={handleLoginModalHide}
class='hand dim fr pr3 pt3'
>
<line
x1='1'
y1='10'
x2='10'
y2='1'
stroke='black'
stroke-width='1'
/>
<line
x1='1'
y1='1'
x2='10'
y2='10'
stroke='black'
stroke-width='1'
/>
</svg>
<main class='black-80'>
<form class='measure center mt3 mb4'>
<fieldset id='sign_up' class='ba b--transparent mh0'>
<div class='mt4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='email'
name='email-address'
id='email-address'
placeholder='Email'
onChange={handleEmailChange}
/>
</div>
<div class='mv4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='password'
name='password'
id='password'
placeholder='Password'
onChange={event => setPassword(event.target.value)}
/>
</div>
<a
href='#0'
class='tc f6 fw6 b link dim br2 ph3 pv3 mb2 dib white bg-blue w-100'
onClick={handleLogin}
>
Sign In
</a>
</fieldset>
<div class='lh-copy mv3'>
<a href='#0' class='f6 link dim black db'>
Forgot your password?
</a>
</div>
<hr class='bb mv3 b--black-10' />
<div class='pt2 flex justify-center'>
<span class='flex b mr2'>Don't have an account?</span>
<a
href='#0'
class='b link dim blue db'
onClick={handleSignupModalShow}
>
Sign Up
</a>
</div>
</form>
</main>
</article>
</div>
</div>
</Modal>
) : null
const signupModal = showSignupModal ? (
<Modal>
<div class='vh-100 dt w-100 bg-black-80 overlay fixed z-999'>
<div class='v-mid dtc tc center '>
<article class='mw6 center br2 bg-white ba b--black-10'>
<svg
viewBox='0 0 12 12'
height='20'
width='20'
version='1.1'
onClick={handleSignupModalHide}
class='hand dim fr pr3 pt3'
>
<line
x1='1'
y1='10'
x2='10'
y2='1'
stroke='black'
stroke-width='1'
/>
<line
x1='1'
y1='1'
x2='10'
y2='10'
stroke='black'
stroke-width='1'
/>
</svg>
<main class='black-80'>
<form class='measure center mt3 mb4'>
<fieldset id='sign_up' class='ba b--transparent mh0'>
<div class='mt4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='email'
name='email-address'
id='email-address'
placeholder='Email'
onChange={handleEmailChange}
/>
</div>
<div class='mv4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='password'
name='password'
id='password'
placeholder='Password'
onChange={handlePasswordChange}
/>
</div>
<a
href='#0'
class='tc f6 fw6 b link dim br2 ph3 pv3 mb2 dib white bg-blue w-100'
onClick={createNewUser}
>
Sign Up
</a>
</fieldset>
</form>
</main>
</article>
</div>
</div>
</Modal>
) : null
return (
<div>
<div class='flex items-center'>
{!isLoaded(auth) ? (
<a class='noselect br2 f6 fw6 dib blue mr2 bg-white ba b--blue no-underline pv3 ph4'>
loading
</a>
) : isEmpty(auth) ? (
<a
class='noselect br2 f6 fw6 dib mr2 bg-white blue grow no-underline pv3 ph4'
onClick={handleLoginModalShow}
>
Log In
</a>
) : (
<div class='flex'>
<span class='noselect br2 f6 fw6 dib white mr2 bg-purple no-underline pv3 ph4'>
<div>{profile.email}</div>
</span>
<a
class='noselect br2 f6 fw6 dib white mr2 bg-green grow no-underline pv3 ph4'
onClick={logout}
>
Log Out
</a>
</div>
)}
</div>
{loginModal}
{signupModal}
</div>
)
}
我的modal.js
组件如下:
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import './style.css'
const modalRoot = document.getElementById('modal-root')
const modalElement = document.createElement('div')
export default function Modal(props) {
useEffect(() => {
modalRoot.appendChild(modalElement)
return () => {
modalRoot.removeChild(modalElement)
}
})
return ReactDOM.createPortal(props.children, modalElement)
}
我的输入位于模态组件内,我使用门户将其显示为叠加层。我已经完成了相关问题并尝试使用其他方法,但似乎没有任何效果。感谢您的帮助!
您的 useEffect
挂钩没有在每次渲染时都会 运行 的依赖项数组。您可能打算在挂载时附加一个子项,因此请尝试一个空的依赖项数组。
export default function Modal(props) {
useEffect(() => {
modalRoot.appendChild(modalElement)
return () => {
modalRoot.removeChild(modalElement)
}
}, []); // Empty dependency array to run once "on mount"
return ReactDOM.createPortal(props.children, modalElement);
}
我试图通过获取更改时的值并将此值存储在本地状态中来跟踪两个登录输入字段的值,这样当用户提交登录时,我就可以从状态中获取当前值.但是,这会导致输入在我输入文本时闪烁,并且在我输入密码字段时也会出现奇怪的故障(光标跳回电子邮件字段)。可以在下面观察到故障(请注意,我没有按 shift-tab 键返回电子邮件字段,当我输入密码字段时,它似乎由于某种原因自动发生)。
以下是我的 profile_tile.js
的代码,我将其作为嵌套在导航栏中的组件:
import React, { useState } from 'react'
import { useFirebase, isLoaded, isEmpty } from 'react-redux-firebase'
import { useSelector } from 'react-redux'
import Modal from '../../modal'
export default function ProfileTile() {
const firebase = useFirebase()
const auth = useSelector(state => state.firebase.auth)
const profile = useSelector(state => state.firebase.profile)
const [showLoginModal, setLoginModalShow] = useState(false)
const [showSignupModal, setSignupModalShow] = useState(false)
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const createNewUser = () => {
firebase.createUser({ email, password })
setLoginModalShow(false)
setSignupModalShow(false)
}
const handleEmailChange = event => {
setEmail(event.target.value)
console.log('EMAIL' + event.target.value)
}
const handlePasswordChange = event => {
setPassword(event.target.value)
console.log('PASSWORD' + event.target.value)
}
const logout = () => {
firebase.logout()
}
const handleLoginModalShow = () => {
setLoginModalShow(true)
setSignupModalShow(false)
}
const handleLoginModalHide = () => {
setLoginModalShow(false)
}
const handleSignupModalShow = () => {
setLoginModalShow(false)
setSignupModalShow(true)
}
const handleSignupModalHide = () => {
setSignupModalShow(false)
}
const handleLogin = () => {
firebase.login({ email: email, password: password })
setLoginModalShow(false)
setSignupModalShow(false)
}
const loginModal = showLoginModal ? (
<Modal>
<div class='vh-100 dt w-100 bg-black-80 overlay fixed z-999'>
<div class='v-mid dtc tc center '>
<article class='mw6 center br2 bg-white ba b--black-10'>
<svg
viewBox='0 0 12 12'
height='20'
width='20'
version='1.1'
onClick={handleLoginModalHide}
class='hand dim fr pr3 pt3'
>
<line
x1='1'
y1='10'
x2='10'
y2='1'
stroke='black'
stroke-width='1'
/>
<line
x1='1'
y1='1'
x2='10'
y2='10'
stroke='black'
stroke-width='1'
/>
</svg>
<main class='black-80'>
<form class='measure center mt3 mb4'>
<fieldset id='sign_up' class='ba b--transparent mh0'>
<div class='mt4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='email'
name='email-address'
id='email-address'
placeholder='Email'
onChange={handleEmailChange}
/>
</div>
<div class='mv4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='password'
name='password'
id='password'
placeholder='Password'
onChange={event => setPassword(event.target.value)}
/>
</div>
<a
href='#0'
class='tc f6 fw6 b link dim br2 ph3 pv3 mb2 dib white bg-blue w-100'
onClick={handleLogin}
>
Sign In
</a>
</fieldset>
<div class='lh-copy mv3'>
<a href='#0' class='f6 link dim black db'>
Forgot your password?
</a>
</div>
<hr class='bb mv3 b--black-10' />
<div class='pt2 flex justify-center'>
<span class='flex b mr2'>Don't have an account?</span>
<a
href='#0'
class='b link dim blue db'
onClick={handleSignupModalShow}
>
Sign Up
</a>
</div>
</form>
</main>
</article>
</div>
</div>
</Modal>
) : null
const signupModal = showSignupModal ? (
<Modal>
<div class='vh-100 dt w-100 bg-black-80 overlay fixed z-999'>
<div class='v-mid dtc tc center '>
<article class='mw6 center br2 bg-white ba b--black-10'>
<svg
viewBox='0 0 12 12'
height='20'
width='20'
version='1.1'
onClick={handleSignupModalHide}
class='hand dim fr pr3 pt3'
>
<line
x1='1'
y1='10'
x2='10'
y2='1'
stroke='black'
stroke-width='1'
/>
<line
x1='1'
y1='1'
x2='10'
y2='10'
stroke='black'
stroke-width='1'
/>
</svg>
<main class='black-80'>
<form class='measure center mt3 mb4'>
<fieldset id='sign_up' class='ba b--transparent mh0'>
<div class='mt4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='email'
name='email-address'
id='email-address'
placeholder='Email'
onChange={handleEmailChange}
/>
</div>
<div class='mv4'>
<input
class='ph2 pv3 input-reset ba b--black-10 w-100'
type='password'
name='password'
id='password'
placeholder='Password'
onChange={handlePasswordChange}
/>
</div>
<a
href='#0'
class='tc f6 fw6 b link dim br2 ph3 pv3 mb2 dib white bg-blue w-100'
onClick={createNewUser}
>
Sign Up
</a>
</fieldset>
</form>
</main>
</article>
</div>
</div>
</Modal>
) : null
return (
<div>
<div class='flex items-center'>
{!isLoaded(auth) ? (
<a class='noselect br2 f6 fw6 dib blue mr2 bg-white ba b--blue no-underline pv3 ph4'>
loading
</a>
) : isEmpty(auth) ? (
<a
class='noselect br2 f6 fw6 dib mr2 bg-white blue grow no-underline pv3 ph4'
onClick={handleLoginModalShow}
>
Log In
</a>
) : (
<div class='flex'>
<span class='noselect br2 f6 fw6 dib white mr2 bg-purple no-underline pv3 ph4'>
<div>{profile.email}</div>
</span>
<a
class='noselect br2 f6 fw6 dib white mr2 bg-green grow no-underline pv3 ph4'
onClick={logout}
>
Log Out
</a>
</div>
)}
</div>
{loginModal}
{signupModal}
</div>
)
}
我的modal.js
组件如下:
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import './style.css'
const modalRoot = document.getElementById('modal-root')
const modalElement = document.createElement('div')
export default function Modal(props) {
useEffect(() => {
modalRoot.appendChild(modalElement)
return () => {
modalRoot.removeChild(modalElement)
}
})
return ReactDOM.createPortal(props.children, modalElement)
}
我的输入位于模态组件内,我使用门户将其显示为叠加层。我已经完成了相关问题并尝试使用其他方法,但似乎没有任何效果。感谢您的帮助!
您的 useEffect
挂钩没有在每次渲染时都会 运行 的依赖项数组。您可能打算在挂载时附加一个子项,因此请尝试一个空的依赖项数组。
export default function Modal(props) {
useEffect(() => {
modalRoot.appendChild(modalElement)
return () => {
modalRoot.removeChild(modalElement)
}
}, []); // Empty dependency array to run once "on mount"
return ReactDOM.createPortal(props.children, modalElement);
}