為了擺脫繁瑣的Dom操作, React提倡組件化, 組件內(nèi)部用數(shù)據(jù)來驅(qū)動(dòng)視圖的方式,來實(shí)現(xiàn)各種復(fù)雜的業(yè)務(wù)邏輯 ,然而,當(dāng)我們?yōu)樵糄om綁定事件的時(shí)候, 還需要通過組件獲取原始的Dom, 而React也提供了ref為我們解決這個(gè)問題.
為什么不能從組件直接獲取Dom?
組件并不是真實(shí)的 DOM 節(jié)點(diǎn),而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu),叫做虛擬 DOM (virtual DOM)。只有當(dāng)它插入文檔以后,才會(huì)變成真實(shí)的 DOM
如果需要從組件獲取真實(shí) DOM 的節(jié)點(diǎn),就要用到官方提供的ref屬性
使用場(chǎng)景
當(dāng)用戶加載頁面后, 默認(rèn)聚焦到input框
import React, { Component } from 'react'; import './App.css'; // React組件準(zhǔn)確捕捉鍵盤事件的demo class App extends Component { constructor(props) { super(props) this.state = { showTxt: "" } this.inputRef = React.createRef(); } // 為input綁定事件 componentDidMount(){ this.inputRef.current.addEventListener("keydown", (event)=>{ this.setState({showTxt: event.key}) }) // 默認(rèn)聚焦input輸入框 this.inputRef.current.focus() } render() { return ( <div className="app"> <input ref={this.inputRef}/> <p>當(dāng)前輸入的是: <span>{this.state.showTxt}</span></p> </div> ); } } export default App;
自動(dòng)聚焦input動(dòng)畫演示
使用場(chǎng)景
為了更好的展示用戶輸入的銀行卡號(hào), 需要每隔四個(gè)數(shù)字加一個(gè)空格
實(shí)現(xiàn)思路:
當(dāng)用戶輸入的字符個(gè)數(shù), 可以被5整除時(shí), 額外加一個(gè)空格
當(dāng)用戶刪除數(shù)字時(shí),遇到空格, 要移除兩個(gè)字符(一個(gè)空格, 一個(gè)數(shù)字),
為了實(shí)現(xiàn)以上想法, 必須獲取鍵盤的BackSpace事件, 重寫刪除的邏輯
限制為數(shù)字, 隔四位加空格
import React, { Component } from 'react'; import './App.css'; // React組件準(zhǔn)確捕捉鍵盤事件的demo class App extends Component { constructor(props) { super(props) this.state = { showTxt: "" } this.inputRef = React.createRef(); this.changeShowTxt = this.changeShowTxt.bind(this); } // 為input綁定事件 componentDidMount(){ this.inputRef.current.addEventListener("keydown", (event)=>{ this.changeShowTxt(event); }); // 默認(rèn)聚焦input輸入框 this.inputRef.current.focus() } // 處理鍵盤事件 changeShowTxt(event){ // 當(dāng)輸入刪除鍵時(shí) if (event.key === "Backspace") { // 如果以空格結(jié)尾, 刪除兩個(gè)字符 if (this.state.showTxt.endsWith(" ")){ this.setState({showTxt: this.state.showTxt.substring(0, this.state.showTxt.length-2)}) // 正常刪除一個(gè)字符 }else{ this.setState({showTxt: this.state.showTxt.substring(0, this.state.showTxt.length-1)}) } } // 當(dāng)輸入數(shù)字時(shí) if (["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(event.key)){ // 如果當(dāng)前輸入的字符個(gè)數(shù)取余為0, 則先添加一個(gè)空格 if((this.state.showTxt.length+1)%5 === 0){ this.setState({showTxt: this.state.showTxt+' '}) } this.setState({showTxt: this.state.showTxt+event.key}) } } render() { return ( <div className="app"> <p>銀行卡號(hào) 隔四位加空格 demo</p> <input ref={this.inputRef} value={this.state.showTxt}/> </div> ); } } export default App;
小結(jié):
虛擬Dom雖然能夠提升網(wǎng)頁的性能, 但虛擬 DOM 是拿不到用戶輸入的。為了獲取文本輸入框的一些操作, 還是js原生的事件綁定機(jī)制最好用~
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com