簡體   English   中英

為什么 React 控制的輸入元素的值沒有從 Chrome 擴展程序正確更新?

[英]Why is the value of a React controlled input element not being updated properly from a Chrome extension?

當我運行此代碼(它是 chrome 擴展的一部分)時,它應該只填寫特定網站的#username#password輸入的信息,在這種情況下為https://wordplay.com/login

但是,輸入元素的值並沒有真正改變。 從視覺上看,輸入字段中有文本,但是當我檢查元素並查看 value 屬性時,它仍然是空白的。 直到我手動在框中鍵入一些內容。 如果我在輸入中輸入一些東西,那么值會更新得很好。

此外,當我嘗試提交表單時,它們都變回空。

const username = document.getElementById('username');
username.value = request.username;

const password = document.getElementById('password');
password.value = request.password; 

🤔 為什么會這樣?

這可能與該站點使用的任何框架有關。

在這種情況下, https ://wordplay.com/login 使用 React 並且這些字段是受控制的輸入,因此該表單上的邏輯不依賴於輸入的 DOM 值,而是依賴於 React 狀態中的值。 從文檔:

受控組件

在 HTML 中,諸如<input><textarea><select>類的表單元素通常會維護自己的狀態並根據用戶輸入進行更新。 在 React 中,可變狀態通常保存在組件的 state 屬性中,並且僅使用setState()更新。

我們可以通過使 React 狀態成為“單一事實來源”來將兩者結合起來 然后呈現表單的 React 組件還控制后續用戶輸入時該表單中發生的事情。 以這種方式由 React 控制其值的輸入表單元素稱為“受控組件”。

✨ Document.execCommand():

因此,最簡單的方法可能是關注輸入,然后使用Document.execCommand()

 const username = document.getElementById('username'); const password = document.getElementById('password'); username.focus(); document.execCommand('insertText', false, 'Alice'); password.focus(); document.execCommand('insertText', false, 'password');
 <input id="username" /> <input id="password" />

⚒️ 手動調度事件:

否則,您可以嘗試在更改它們的值后使用這些字段中的Event() 構造函數手動調度changeinput和/或blur事件 在這種情況下,只有input有效。

另外,請注意Event()的第二個可選參數包含一個字段bubbles ,默認情況下為false 你需要那個是true 否則,這將不起作用,因為 React 正在偵聽document上的事件。

此外,您可能還需要使用Element.setAttribute() ,因為這將更新 DOM 上的value屬性(字段上的初始值),而element.value將更新當前值(以及顯示值)。 但是,在這種情況下,不需要它。 有關更多信息,請參閱HTML 中的屬性和屬性有什么區別? .

這種方法可能有一些時間問題,您可能需要在更新多個輸入時使用setTimeout來處理,所以如果第一個有效,我會改用那個。

 const username = document.getElementById('username'); // This updates the value displayed on the input, but not the DOM (you can do that with setAttribute, // but it's not needed here): username.value = 'Bob'; // Dispatch an "input" event. In some cases, "change" would also work: username.dispatchEvent(new Event('input', { bubbles: true })); // It looks like only one field will be updated if both events are dispatched // straight away, so you could use a setTimeout here: setTimeout(() => { const password = document.getElementById('password'); password.value = 'password'; password.dispatchEvent(new Event('input', { bubbles: true })); });
 <input id="username" /> <input id="password" />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM