获取导致 React 闪烁的输入值
Posted
技术标签:
【中文标题】获取导致 React 闪烁的输入值【英文标题】:Getting value of input causing flickering in React 【发布时间】:2020-04-20 07:20:05 【问题描述】:我试图通过获取更改时的值并将此值存储在本地状态中来跟踪两个登录输入字段的值,以便当用户提交登录时,我可以从状态中获取当前值。但是,当我在其中输入文本时,这会导致输入闪烁,并且当我在密码字段中输入时也会出现奇怪的故障(光标跳回电子邮件字段)。可以在下面观察到故障(请注意,我没有切换回电子邮件字段,当我输入密码字段时,由于某种原因,它似乎是自动发生的)。
以下是我的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)
我的输入位于模态组件中,我使用门户将其显示为叠加层。我已经解决了相关问题并尝试使用其他方法,但似乎没有任何效果。感谢您的帮助!
【问题讨论】:
你能发布你的整个组件吗?当我使用您发布的确切代码创建沙箱时,它完全按预期工作。肯定还有更多的事情发生。 @MatthewMoran 抱歉,我认为如果我发布整个内容就太过分了。我已经用相关组件更新了它。 您的useEffect
钩子没有将在每个渲染上运行的依赖项数组。您可能打算在安装时附加一个孩子,所以尝试一个空的依赖数组。
@DrewReese 哇,你是对的,这对我有用。如果您将此作为答案发布,我会接受。
【参考方案1】:
您的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);
【讨论】:
以上是关于获取导致 React 闪烁的输入值的主要内容,如果未能解决你的问题,请参考以下文章