获取导致 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 闪烁的输入值的主要内容,如果未能解决你的问题,请参考以下文章

React:状态更新时 UI 闪烁

React Native Paper TextInput in Modal,输入字符后光标向后闪烁

Material UI 手风琴在折叠或展开时会导致页面闪烁

每秒重新加载 Tableview 部分会导致闪烁

在输入/复制到富文本框时防止闪烁

react-native TouchableHighlight 禁用 onPress 颜色闪烁