国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[ 一起學(xué)React系列 -- 5 ] 如何優(yōu)雅得使用表單控件

Charlie_Jade / 2194人閱讀

摘要:假如我們從后臺拉取一個數(shù)據(jù)要填入輸入框,那么必須得使用受控組件,因為非受控組件只能被用戶輸入。不影響正常輸入填充該輸入框的默認(rèn)值,此時不顯示內(nèi)容。

網(wǎng)頁中使用的form表單大家肯定都再熟悉不過了,它主要作用是用來收集和提交信息。
React中的表單組件與我們普通的Html中的表單及其表現(xiàn)形式?jīng)]有什么不同,所以如何使用表單我覺得再拿出來說可能是畫蛇添足、毫無意義。不過再怎么樣也不能辜負(fù)大家對標(biāo)題的期待吧,本篇內(nèi)容筆者將以控件為主體進(jìn)行記錄。

那么問題來了,何為控件?
在React中,將form組件(
)下的所有子組件統(tǒng)稱為控件,比如常用的input:text, Select, input:radio等等。

對于一個表單來說,

只是這個表單的載體,它具體能做哪些事還是由其內(nèi)部的控件決定的。所以如何將這些控件有效得組織起來形成一個表單體系就顯得尤為重要。同時React也將控件分為受控組件(Controlled Components)和非受控組件(uncontrolled components)。不過有一點需要明確下這個分類依據(jù)并不是以組件的類別來分類而是以使用方式來分類的,具體咱們下面接著說。

受控組件

官方對受控組件的定義是:

An input form element whose value is controlled by React in this way is called a “controlled component”

簡而言之就是用戶輸入型的表單控件是由React體系來管理。比如一個輸入框,我們可以通過其value對其賦值進(jìn)而實現(xiàn)改變輸入框中的值的目的(當(dāng)然不只限于輸入框,還有下拉框、文本域等)。而這也是受控組件可以被React控制的關(guān)鍵所在。先舉個例子:

import React, {Component} from "react";

class ControlledInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: "React"
        }
    }

    render() {
        return (
            
        )
    }
}
export default ControlledInput;

通過例子我們能看出在這個組件的State中我們定義了inputValue這個字段并且將它以value的形式賦給了一個輸入框,此時這個組件的表現(xiàn)如下:

不過擁有雪亮眼睛的朋友一眼就能看出來兩個"問題":

此時的輸入框不管怎么敲擊鍵盤,輸入框中的值都是不變的。熟悉原生輸入框的朋友都知道,一旦它的value屬性被賦了值那么相當(dāng)于輸入框的內(nèi)容被寫死了,如果想改變輸入框的內(nèi)容那就得改變value屬性的值

輸入框的value屬性的值是組件State中的inputValue字段。

根據(jù)上面兩個"問題"我們可以預(yù)見到:如果通過setState方法去改變inputValue的值,這樣React會重新渲染組件節(jié)點中的inputValue值,不就相當(dāng)于改變了輸入框的value屬性值了么?
那就動手實踐下,我們在這個組件中添加一個按鈕用它來改變inputValue值:

import React, {Component} from "react";

class ControlledInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: "React"
        }
    }

    changeHandler = () => {
        this.setState({
            inputValue: "React Form"
        })
    };

    render() {
        return (
            
) } } export default ControlledInput;

效果與我們所遇見的一樣。不過實際開發(fā)中我們可不能通過點擊按鈕去改變輸入框的值,因為輸入框需要用戶的實際輸入,所以我們需要在輸入框DOM節(jié)點上綁定onChange實踐,將用戶實際輸入的值set給組件的State。修改方式如下:

import React, {Component} from "react";

class ControlledInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: "React"
        }
    }

    inputHandler = (e) => {
        const content = e.target.value;
        this.setState({
            inputValue: content
        })
    };

    render() {
        return (
            
) } } export default ControlledInput;

每當(dāng)輸入框中的內(nèi)容發(fā)生變動我們就將變動后的內(nèi)容通過State重新渲染給輸入框的value屬性。說到這里,可能就有人認(rèn)為這不是脫褲子放屁嗎?為什么要在用戶輸入完后再繞一圈?且不急,后面會有具體說明。我們繼續(xù)往下說?。。?br>上面的代碼就是將輸入框作為一個受控組件在使用。具體流程我們可以畫一個圖,這樣更為直觀也更容易理解。

這就是受控組件的實現(xiàn)方式流程圖。這里僅僅是用輸入框作為演示主體,其實還有下拉框、文本域這類可以產(chǎn)生更多交互的Html標(biāo)簽(或者說是可以通過value屬性改變其外在表現(xiàn)的Html標(biāo)簽)。不過這里筆者想特地排除下單選框和復(fù)選框,因為它們的狀態(tài)太過單一。

非受控組件

說到非受控組件我相信大家都能意會它的是什么意思,就是它的狀態(tài)由自己維護(hù),實際上這也是Html標(biāo)簽原來的樣子。比如輸入框被輸入了什么值,那這個值就被輸入框自己管理,不由外來因素管理?;蛟S這么做會顯得更為簡單,筆者一直也這么認(rèn)為(僅限一般情況下)。
這里我們繼續(xù)以輸入框為主要演示對象繼續(xù)往下說。對于一個輸入框如果我們想獲取它的輸入內(nèi)容,一般有有兩個方法,一個是綁定事件在其輸入期間同步的獲取輸入值,還有一個辦法是通過原生DOM對象的value獲取輸入值。不過對于非受控組件我們應(yīng)該最大限度得保證其純凈,如果給其綁定一個事件來獲取輸入值那么相當(dāng)于用受控組件的實現(xiàn)方式去處理它會顯得很冗余,所以通過原生DOM去獲取輸入值是最Nice的辦法當(dāng)然React也提供了訪問原生DOM的方法: React.createRef()。
這是React提供的新的訪問原生DOM的方法,墻裂建議這樣使用;
同樣我們也使用它改變一下原來的代碼:

import React, {Component} from "react";

class ControlledInput extends Component {
    constructor(props) {
        super(props);
        this.input = React.createRef();
    }

    inputHandler = () => {
        const originalDom = this.input.current;//current代表原生DOM對象
        const content = originalDom.value;
        alert(content);
    };

    render() {
        return (
            
) } } export default ControlledInput;

運(yùn)行結(jié)果很完美?。?!非受控組件的實現(xiàn)及使用方法就是這么簡單,我們只管取值就行了,其它由它們自己管理就好了。

受控組件與非受控組件的不同及啟示

通過上面的介紹我們了解了受控組件與非受控組件及其實現(xiàn)、使用方式。它們的不同之處筆者這里用一句話總結(jié)下:

受控組件的value值受React管理;非受控組件的value值由自身管理;

那這句話能給我們什么樣的啟示?
首先看非受控組件的value值由自身管理,對于非受控組件我們好像除了拿值其它的什么都干不了,實際情況的卻如此,pass?。?br>再看受控組件的value值受React管理,前面我們知道受控組件對于用戶輸入的值需要從State中繞一下再到組件本身。那么我們可不可以在這個“繞”的過程中做點什么?比如在setState之前對用戶輸入的內(nèi)容做點手腳什么的...帶著這個想法,我們往下看!

如何選擇受控組件與非受控組件

既然React將form控件分為受控組件與非受控組件自然有它自己的道理,那么我們實際開發(fā)中應(yīng)該如何優(yōu)雅得選擇它們?假如我們只是單純得獲取用戶的輸入,那我們會本能的選擇非受控組件,因為它使用很方便不需要寫那么多復(fù)雜的邏輯;假如我們想對用戶的輸入做點手腳,比如字母轉(zhuǎn)大小寫等等...因為原生input標(biāo)簽不具備此功能,或許我們就得使用受控組件。當(dāng)然一位外國友人對如何選擇受控組件與非受控組件發(fā)表了自己的看法,筆者這里做個搬運(yùn)。不想看或者沒法看的朋友可以看下面的搬運(yùn)內(nèi)容,跳過廢話直接上結(jié)論:

一次性數(shù)據(jù)獲取可以任意使用其中一種。不過筆者覺得選擇非受控組件會更為便捷,不需要寫一大堆邏輯

提交時進(jìn)行驗證可以任意使用其中一種。這個仁者見仁智者見智,不過筆者還是覺得非受控組件會更好

實時驗證使用受控組件。因為我們在用戶輸入過程中對輸入值進(jìn)行實時驗證,而非受控組件不支持這么做,初非你用第三方庫;

有條件地禁用提交按鈕使用受控組件。禁用提交按鈕的前提是輸入值不合法,參考第三條。

對輸入值進(jìn)行格式化使用受控組件。非受控組件輸入什么就是什么,我們無法去改變;而受控組件我們可以在獲取到輸入值的時候?qū)斎胫颠M(jìn)行轉(zhuǎn)換,比如大小寫獲取貨幣轉(zhuǎn)換等等,最后render回控件中。

對一條數(shù)據(jù)盡心多次輸入使用受控組件。同樣的非受控組件的狀態(tài)由自身管理,而對于受控組件我們可以對輸入值做更多的處理

動態(tài)輸入使用受控組件。假如我們從后臺拉取一個數(shù)據(jù)要填入輸入框,那么必須得使用受控組件,因為非受控組件只能被用戶輸入。

心得:在表單中使用單選框和復(fù)選框

為什么多帶帶將單選框和復(fù)選框拉出來軍訓(xùn)?是因為它們的狀態(tài)單一不需要用戶輸入且它們的value屬性并不和自身表現(xiàn)有直接關(guān)系。例如我們無法通過對單選框的value設(shè)置為true從而讓它變?yōu)檫x中的狀態(tài)。而且單選框和復(fù)選框基本都是成群結(jié)隊出現(xiàn)的,所以從受控組件與非受控組件角度來處理它們顯然不適合。這里筆者推薦兩種處理方式:

事件代理

比如這樣寫:

import React, {Component} from "react";

class ControlledInput extends Component {

    constructor(props) {
        super(props);
        this.parent = React.createRef();
    }

    componentDidMount() {
        this.parent.current.addEventListener("change", (event) => {
            //do something
            console.log(event);
        })
    }

    componentWillUnmount() {
        this.parent.current.removeEventListener("change");

    }

    render() {
        return (
            
) } } export default ControlledInput;

在一群單選框或者復(fù)選框外層包一個div并且綁定事件監(jiān)聽。當(dāng)我們點擊它們的時候就會獲取到對于的事件對象,然后就可以做你想做!

動態(tài)生產(chǎn)

所謂動態(tài)生產(chǎn)就是用一個function生成所需要的一群單選框或者復(fù)選框,同時給它們綁定相關(guān)事件,比如:

import React, {Component} from "react";

class ControlledInput extends Component {

    constructor(props) {
        super(props);
        this.checkBoxs = ["A", "B", "C"];
    }

    //Process checkbox group
    createCheckBoxes = () => this.checkBoxs.map(checkbox => (
        
    ));

    checkBoxChange = (e) => {
        //do something
        console.log(e);
    };

    render() {
        return (
            
Checkboxes: {this.createCheckBoxes()}
) } } export default ControlledInput;

對于這兩種方法,大家仁者見仁智者見智。不過如果有其他的方法歡迎留言 :)

寫在最后

其實也沒啥寫的,就想再提一下輸入框的三個屬性幫助不熟悉的朋友多了解下。對于Html輸入框很熟悉的朋友此處可以跳過了。

placeholder: 主要用來提示用戶這個輸入框需要輸入什么樣的內(nèi)容。不影響正常輸入!

defaultValue: 填充該輸入框的默認(rèn)值,此時不顯示placeholder內(nèi)容。不影響正常輸入!

value: 起到填充輸入框內(nèi)容的作用;與defaultValue不能共存;且一旦設(shè)置了value屬性(即使為空或者無值)那么該輸入框?qū)o法進(jìn)行輸入。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108510.html

相關(guān)文章

  • [ 一起學(xué)React系列 -- 8 ] React中的文件上傳

    摘要:前言本期的主題是在中如何實現(xiàn)文件上傳。文件上傳解決方案目前比較主流的解決方案就是表單或者和表單來實現(xiàn)。文件上傳解決方案表單利用表單組件進(jìn)行文件上傳是遠(yuǎn)古時期就一直在用的方法而且還真經(jīng)久不衰,厲害了。 終于抽出時間來繼續(xù)更新自己的博客,最近忙得夠嗆...對于該系列博客不知道大家有沒有這樣的看法,對于React常見的基礎(chǔ)東西并沒有過多或者詳細(xì)列出,感覺有點不符合系列標(biāo)題。的確,筆者一開始也...

    Travis 評論0 收藏0
  • [ 一起學(xué)React系列 -- 0 ] React技術(shù)棧學(xué)習(xí)路線

    摘要:的出現(xiàn)真可謂是前端界的福音,正與之宗旨所說,。據(jù)統(tǒng)計,目前世界上有的項目使用了。技術(shù)棧學(xué)習(xí)路線直到前段時間筆者的朋友給推薦了一個,真是欣喜若狂也更加堅定了自己在繼續(xù)前進(jìn)的想法。這是一個外國友人總結(jié)的一套技術(shù)棧學(xué)習(xí)路線,先給傳送門。 我相信點進(jìn)來的同學(xué)都是沖著標(biāo)題來的,當(dāng)然本文也不會讓各位失望。不過在正式介紹標(biāo)題所述的內(nèi)容之前,我們不妨先放下技術(shù),一起回顧下自己做前端技術(shù)的心路歷程。 前...

    Java3y 評論0 收藏0
  • [ 一起學(xué)React系列 -- 9 ] React中的文件下載

    摘要:本篇所說的文件下載也是基于和或者都行。的返回值是一個有意思的對象,它包含了很多方法,其中一個方法就是。通過的響應(yīng)頭獲取到文件名。接下來就是對標(biāo)簽的一系列操作,然后模擬點擊事件觸發(fā)下載動作。 距離上次博文更新已經(jīng)快一個月了,期間忙于各種事情無法脫身。今天難得閑暇 and then 就來更新啦...上篇中我們了解了下載React中如何實現(xiàn)文件的上傳,雖然不算什么高大上的技術(shù)但實際開發(fā)的時候...

    Jacendfeng 評論0 收藏0
  • [ 一起學(xué)React系列 -- 6 ] 秘術(shù)之時間旅行-1

    摘要:所謂的時間旅行從廣義上來說無非就是三個動作回到過去進(jìn)入未來回到現(xiàn)在,這個無論是從現(xiàn)實還是前端技術(shù)來說都是可靠的。單從技術(shù)棧來說,時間旅行不是一門技術(shù)而是一個思想套路。 標(biāo)題看起來挺新穎的,筆者都覺得很高大上是不是哈哈... 拋轉(zhuǎn) 時間旅行在生活中是一個非常吸引人的概念,雖然現(xiàn)在無法實現(xiàn)但說不定未來的某天就實現(xiàn)了!然后就穿梭會過去殺掉小時候的自己然后就開始懵逼自己是誰類似的狗血劇情......

    付倫 評論0 收藏0
  • [ 一起學(xué)React系列 -- 4 ] 透傳的Context

    摘要:官方對的介紹是意思就是提供了一種通過組件樹傳遞數(shù)據(jù)的方法,而無需在每個級別手動傳遞。這也是基于重要物證哈哈實例使用學(xué)習(xí)技術(shù)最終是要有產(chǎn)出的。依然被視作一個組件,不過不同的是它的子組件必須是一個方法并且該方法接收當(dāng)前對象并最終返回一個節(jié)點。 拋轉(zhuǎn)引玉 通過上一篇的科普我們知道如果父節(jié)點需要向子節(jié)點傳遞數(shù)據(jù),那么就得通過Props來實現(xiàn);那么擺在我們眼前的就有一個問題了:現(xiàn)有N個節(jié)點并且它...

    firim 評論0 收藏0

發(fā)表評論

0條評論

Charlie_Jade

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<