15、react 的 非受控组件 和 受控组件
react 的 非受控組件 和 受控組件
組件分為 非受控組件 和 受控組件,這兩種有什么區別呢,單說概念不好理解,那我們通過一個案例來說明一下,一下子就可以弄懂了,很簡單的。
案例
還是,以案例的方式開頭,在實現案例的同時說明一下兩個類型的組件。
我們做一個表單,點擊表單提交參數對吧。
好,我們就做上面效果圖一樣的案例。
非受控組件
首先我們先寫一個表單吧。我這邊直接寫代碼了,一些具體的寫法就不細說了,看不懂的直接翻我以前的博客,都有講解。
<!-- 此處必須寫 text/babel --><script type="text/babel">// 創建組件class Login extends React.Component {render() {return (<form action="http://www.baidu.com">賬號:<input type="text" name="username" /> <br />密碼:<input type="password" name="password" /><br /><button>登 錄</button></form>)}}// 渲染組件ReactDOM.render(<Login />, document.getElementById("app"))</script>上面的代碼我相信都可以看懂是吧?寫了一個單純的表單,點擊按鈕他會把我們的賬號密碼帶到百度去,我們保存刷新看一下效果先。
OK,到這里都是沒有問題的吧。
但是有點瑕疵啊,就是我們在做項目的時候呢,一般是 ajax 請求,我們的頁面不能刷新,包括地址,頁面都是不能動的,顯然寫到這里有瑕疵,不對,所以我們需要修改一下。
怎么修改呢,有人說不想跳轉頁面就把 form 表單的 action 刪掉就可以了嘛! 我們試一下哈。
render() {return (<form>賬號:<input type="text" name="username" /> <br />密碼:<input type="password" name="password" /><br /><button>登 錄</button></form>)}代碼我們已經把 form 表單的 action 去掉了,我們在操作一遍看一下效果:
我們看到哈,action 刪除掉之后,點擊按鈕之后,頁面確實不跳轉了,但是呢,地址變了對吧?
這不行,地址變得原因是因為啥呢,就是 form 表單默認操作的,我們不想讓地址變的話,取消掉 form 的默認提交方式,我們自己寫彈窗信息就可以了吧。
form 表單默認提交的方式是 onsubmit 方法,我們重新設置一下,當然了, react 中使用不能寫 onsubmit,而是改為了 onSubmit,切記。我們修改代碼,首先取消掉他的默認事件,我們不用了,然后自己寫一個事件先取消掉 form 的默認事件。
<!-- 此處必須寫 text/babel --><script type="text/babel">// 創建組件class Login extends React.Component {handleSubmit = (event) => {event.preventDefault() // 阻止默認事件,即表單提交組織}render() {return (<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>賬號:<input type="text" name="username" /> <br />密碼:<input type="passwofd" name="password" /><br /><button>登 錄</button></form>)}}// 渲染組件ReactDOM.render(<Login />, document.getElementById("app"))</script>OK,我們在 handleSubmit 中取消了他的默認事件,這樣就不會在點擊按鈕的時候自動跳轉和修改路徑了。
我們可以看到,點擊按鈕的時候已經不會再跳轉也不會修改我們路徑了哈。
接下來就是彈窗展示數據了。
上一篇博客說了要盡可能的減少使用 refs ,通過事件源獲得數據,這個地方可以用嗎?
顯然是不可以的吧?因為我們操作的 dom 是按鈕,但是我們在 按鈕的點擊事件里面想要獲取的是兩個 input 輸入框的值,顯然是不可以的,所以說還是得用 refs。
那這個就很簡單了,不詳細說了。
<!-- 此處必須寫 text/babel --><script type="text/babel">// 創建組件class Login extends React.Component {handleSubmit = (event) => {event.preventDefault() // 阻止默認事件,即表單提交組織const { username, password } = thisalert(`你輸入的賬號是 ${username.value},你輸入的密碼是 ${password.value}`)}render() {return (<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>賬號:<input ref={c => this.username = c} type="text" name="username" /> <br />密碼:<input ref={c => this.password = c} type="passwofd" name="password" /><br /><button>登 錄</button></form>)}}// 渲染組件ReactDOM.render(<Login />, document.getElementById("app"))</script>保存,看一下效果。
OK,案例的要求就寫完了,效果一模一樣對吧!
上邊我們寫的組件,就是 非受控組件。很多寶子懵了吧?為啥啊?為啥他就是非受控組件啊!
非受控組件的特點就是 現用現取 啊!
啥是現用現取,你看上邊我們寫的代碼,我們點擊按鈕需要顯示彈窗展示數據吧?我們在點擊彈窗的時候才去獲取的賬號和密碼,是用的時候現取的數據吧?這就是現用現取,只要是現用現取,就是非受控組件。
好,非受控組件就到這里。
【該部分相關代碼資料】:我是𝒆𝒅. 的 gitee
受控組件
上面我們說了 非受控組件,很多人可能不是很理解,覺得這是很正常的邏輯啊,沒關系,我們現在說一下受控組件,說完受控組件,就會有一種恍然大明白的感覺。
我們還是上邊的案例。
我們知道 input 輸入框是不是有一個 onchange 事件啊!就是當我們 input 輸入框的內容改變后就會觸發,當然,react 里面要 onChange 這樣寫,我們試一下。
saveUsername = (event) => {console.log(event.target.value)}render() {return (<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>賬號:<input onChange={this.saveUsername} type="text" name="username" /> <br />密碼:<input ref={c => this.password = c} type="passwofd" name="password" /><br /><button>登 錄</button></form>)}我們打印一下 賬號輸入框改變的數據:
OK,效果是可以的哈。
那我們做這樣一件事。
當我們每當賬號、密碼內容改變的時候,我們都把改變后的數據放到狀態 state 當中保存起來,點擊的時候,就可以直接從 狀態 里面獲取展示彈窗。沒問題吧!
修改一下代碼:
<!-- 此處必須寫 text/babel --><script type="text/babel">// 創建組件class Login extends React.Component {// 首先初始化狀態,嚴禁不初始化狀態直接使用state = { username: '', password: '' }handleSubmit = (event) => {event.preventDefault() // 阻止默認事件,即表單提交組織const { username, password } = this.state // 從 state 種獲取數據alert(`你輸入的賬號是 ${username},你輸入的密碼是 ${password}`)}saveUsername = (event) => {// console.log(event.target.value)this.setState({ username: event.target.value }) // 把賬號的數據值存到狀態}savePassword = (event) => {// console.log(event.target.value)this.setState({ password: event.target.value }) // 把密碼的數據值存到狀態}render() {return (<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>賬號:<input onChange={this.saveUsername} type="text" name="username" /> <br />密碼:<input onChange={this.savePassword} type="passwofd" name="password" /><br /><button>登 錄</button></form>)}}// 渲染組件ReactDOM.render(<Login />, document.getElementById("app"))</script>看上面代碼,都懂是吧?仔細看哈,我們存到狀態里面的直接就是 數據值,不是 dom 節點,所以說展示彈窗的時候直接取值就可以了,不需要在 .value。保存刷新查看效果:
OK。效果也實現了,這個代碼寫的組件,就是受控組件。我們把數據在改變的時候就保存到 state 種,用的時候不是從 input 里面現取的,所以是 受控組件。
對比兩個類型的組件。應該理解兩者的區別了吧!
好的今天就到這兒,晚安了寶子們~
【本部分關鍵代碼資料】:我是𝒆𝒅. 的 gitee
總結
以上是生活随笔為你收集整理的15、react 的 非受控组件 和 受控组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抖音App已正式更名,短视频在名称中消失
- 下一篇: ZBrush - 动物毛发制作及渲染