react文檔——表單

表單

在 React 中颅湘,HTML 表單元素和其它的 DOM 元素有一點(diǎn)不同簸喂,因?yàn)楸韱卧靥焐谋3忠恍﹥?nèi)部狀態(tài)吗伤。例如珠移,這個(gè)普通的 HTML 表單接收一個(gè)單一的 name:

<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

這個(gè)表單有默認(rèn)的 HTML 表單行為茁裙,當(dāng)用戶提交表單時(shí)喝峦,會(huì)跳轉(zhuǎn)到新的頁面。如果你想在 React 中有這個(gè)行為呜达,它也是有效的谣蠢。但是大多數(shù)情況下,讓一個(gè) JavaScript 函數(shù)來處理表單的提交和訪問用戶輸入的數(shù)據(jù)是比較方便的查近。實(shí)現(xiàn)這個(gè)效果的標(biāo)準(zhǔn)方式是使用稱為“受控組件”的技術(shù)眉踱。

受控組件

在 HTML 中,表單元素如<input>霜威、<textarea><select>通程冈基于用戶的輸入維護(hù)或更新自身的狀態(tài)。在 React 中戈泼,可變的狀態(tài)通常保存在組件的 state 屬性婿禽,并且只能使用setState()來更新。

我們可以通過使 React state 成為“單一數(shù)據(jù)源”來使兩者結(jié)合大猛。然后 React 組件渲染一個(gè)表單并控制這個(gè)表單在隨后的用戶輸入中發(fā)生了什么扭倾。用這種方法被 React 控制 value 的 input 表單元素被稱為“受控組件”。

例如挽绩,我們想使之前的例子在提交的時(shí)候顯示輸入的 name膛壹,我們把這個(gè)表單寫成受控組件:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen上試試。

由于我們的表單設(shè)置了value屬性,value 的顯示一直會(huì)是this.state.value的值模聋,使 React state 成為單一數(shù)據(jù)源肩民。由于每次輸入都會(huì)運(yùn)行handleChange來更新 React state,用戶的輸入會(huì)作為 value 的更新顯示链方。

使用一個(gè)受控組件持痰,每一個(gè) state 的變化都會(huì)有一個(gè)與之相關(guān)聯(lián)的處理函數(shù)。這使得修改或驗(yàn)證用戶的輸入變得更簡單明確祟蚀。例如工窍,我們想讓用戶的輸入強(qiáng)制變成大寫,我們可以把handleChange寫成這樣:

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});
}

textarea 標(biāo)簽

在 HTML 中暂题,<textarea>元素通過它的子元素定義它的文本:

<textarea>
  Hello there, this is some text in a text area
</textarea>

在 React 中<textarea>使用一個(gè)value屬性代替。這種方式究珊,textarea表單的編寫和編寫單行 input 表單非常類似:

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <textarea value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

注意薪者,this.state.value是在構(gòu)造函數(shù)中初始化的,所以文本域一開始就有一些文本在里面剿涮。

select 標(biāo)簽

在 HTML 中言津,<select>創(chuàng)建一個(gè)下拉列表。例如取试,這段 HTML 代碼創(chuàng)建了一個(gè)關(guān)于風(fēng)味的下拉列表:

<select>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
  <option selected value="coconut">Coconut</option>
  <option value="mango">Mango</option>
</select>

注意悬槽,由于selected屬性,Coconut 選項(xiàng)是被默認(rèn)選擇的瞬浓。React 不使用selected屬性初婆,而是在select標(biāo)簽根上使用value屬性。這在一個(gè)受控組件中更方便猿棉,因?yàn)槟銉H需在一個(gè)地方更新它磅叛。例如:

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite La Croix flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen上試試。

總的來說萨赁,這使得<input type="text">弊琴、<textarea><select>工作方式非常相似——它們都接收一個(gè)value屬性,你可以使用它來實(shí)現(xiàn)一個(gè)受控組件杖爽。

替代受控組件

有時(shí)使用受控組件是乏味的敲董,因?yàn)槟阈枰ㄟ^一個(gè)組件為所有的數(shù)據(jù)變化的方式和管道處理所有的輸入 state 編寫事件處理器。當(dāng)你轉(zhuǎn)換一個(gè)已存在的代碼庫到 React慰安,或使用非 React 庫整合一個(gè) React 應(yīng)用時(shí)腋寨,這一點(diǎn)尤為惱人。在這種情況下化焕,你可能想查看非受控組件精置,一個(gè)實(shí)現(xiàn) input 表單的另類技術(shù)。

下一步

提升 State

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锣杂,一起剝皮案震驚了整個(gè)濱河市脂倦,隨后出現(xiàn)的幾起案子番宁,更是在濱河造成了極大的恐慌,老刑警劉巖赖阻,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝶押,死亡現(xiàn)場離奇詭異,居然都是意外死亡火欧,警方通過查閱死者的電腦和手機(jī)棋电,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苇侵,“玉大人赶盔,你說我怎么就攤上這事∮芘ǎ” “怎么了于未?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長陡鹃。 經(jīng)常有香客問我烘浦,道長,這世上最難降的妖魔是什么萍鲸? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任闷叉,我火速辦了婚禮,結(jié)果婚禮上脊阴,老公的妹妹穿的比我還像新娘握侧。我一直安慰自己,他們只是感情好嘿期,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布藕咏。 她就那樣靜靜地躺著,像睡著了一般秽五。 火紅的嫁衣襯著肌膚如雪孽查。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天坦喘,我揣著相機(jī)與錄音盲再,去河邊找鬼。 笑死瓣铣,一個(gè)胖子當(dāng)著我的面吹牛答朋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棠笑,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼梦碗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洪规,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤印屁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后斩例,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雄人,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年念赶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了础钠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叉谜,死狀恐怖旗吁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情停局,我是刑警寧澤很钓,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站翻具,受9級特大地震影響履怯,放射性物質(zhì)發(fā)生泄漏回还。R本人自食惡果不足惜裆泳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柠硕。 院中可真熱鬧工禾,春花似錦、人聲如沸蝗柔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癣丧。三九已至槽畔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胁编,已是汗流浹背厢钧。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嬉橙,地道東北人早直。 一個(gè)月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像市框,于是被迫代替她去往敵國和親霞扬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容