/

如何解決 React 登入表單狀態和瀏覽器自動填充的問題

如何解決 React 登入表單狀態和瀏覽器自動填充的問題

在進行一個項目時,我遇到了一個問題,這個項目是使用 React 構建的表單,並且與瀏覽器的自動填充功能有關。

你知道嗎,當瀏覽器自動填寫你的用戶名/密碼,因為你之前已經輸入過?

那就是自動填充,這也是我遇到問題的原因。特別是在 Chrome 和 Firefox 上複製這個問題,但任何瀏覽器都可能碰到這個問題。

這個表單是使用 useState 鉤子構建的一個普通而簡單的表單。

這是表單中的一個示例「email」字段:

1
2
3
4
5
import { useState } from 'react'

//...

const [email, setEmail] = useState('')
1
2
3
4
5
6
7
<input
id='email'
type='email'
name='email'
value={email}
onChange={(event) => setEmail(event.target.value)}
/>

當你在這個字段中輸入電子郵件時,email 的值會使用 setEmail 進行更新,這樣我就可以在表單提交事件中使用它,然後將它發送到服務器。

在某個時刻,我意識到瀏覽器正在自動填寫電子郵件地址和密碼,但是 React 卻沒有識別到它!

可能是因為它在 React 完全運行之前就填寫了該字段,所以無法截取該事件。

我進行了一些研究,不同瀏覽器的不一致性和自動填充工作方式的差異讓我感到困惑,因此我不得不創建一個簡單的解決方案。

我使用了 useRefuseEffect 來實現它:

1
import { useState, useEffect, useRef } from 'react'

我創建了一個 ref:

1
const emailField = useRef(null)

並將它附加到 JSX 的輸入字段上:

1
2
3
4
5
6
7
8
<input
ref={emailField}
id='email'
type='email'
name='email'
value={email}
onChange={(event) => setEmail(event.target.value)}
/>

然後,我添加了一段代碼,每 100 毫秒查找字段的值,並調用 setEmail() 更新它:

1
2
3
4
5
6
7
8
9
useEffect(() => {
let interval = setInterval(() => {
if (emailField.current) {
setEmail(emailField.current.value)
// 對所有自動填寫的字段進行相同的處理
clearInterval(interval)
}
}, 100)
})

這並不是理想的解決方案,它涉及到 DOM 操作,而在使用 React 這樣的庫時我們應該避免使用 DOM 操作,但它可以解決這個問題。

如果沒有自動填充,這個解決方案只會等到輸入第一個字符時才停止循環。

tags: [“React”, “form”, “browser autofill”, “useState”, “useEffect”, “useRef”]