React之受控元件和非受控元件

青衫無名發表於2018-06-01

在React中,所謂受控元件和非受控元件,是針對表單而言的。

表單受控元件

  • 表單元素依賴於狀態,表單元素需要預設值實時對映到狀態的時候,就是受控元件,這個和雙向繫結相似.
  • 受控元件,表單元素的修改會實時對映到狀態值上,此時就可以對輸入的內容進行校驗.
  • 受控元件只有繼承React.Component才會有狀態.
  • 受控元件必須要在表單上使用onChange事件來繫結對應的事件.
class Control extends React.Component {
    // 這樣的寫法也是宣告在例項上的物件
    state = {// 給元件狀態設定預設值,在實時修改時進行校驗
        username: "zf",
        pwd: "123"
    }

    // e為原生的事件繫結物件
    handleChange = (e) => {
        // 獲取原生物件上的屬性
        let name = e.target.name;
        // 根據表單元素的name名稱進行匹配,比如使用者名稱的name是username,那新輸入的值將更新原來的值
        this.setState({
            [name]: e.target.value
        })
    }

    render() {
        return (
            <div>
                <p>{this.state.username}</p>
                使用者名稱:<input
                    name="username"
                    type="text"
                    value={this.state.username}
                    onChange={this.handleChange} /> <br />

                <p>{this.state.pwd}</p>
                密碼:<input
                    name="pwd"
                    type="text"
                    value={this.state.pwd}
                    onChange={this.handleChange} /> <br />
            </div>
        )
    }
}

複製程式碼

受控元件顯示結果

1644727ebae39655?imageslim

怎麼樣,這個效果是不是和雙向繫結很相似?

注意:

  • 在受控元件中,如果沒有給輸入框繫結onChange事件,將會收到react的警告
  • 並且此時輸入框除了預設值,是無法輸入其他任何引數的
class Control extends React.Component {
    constructor() {
        super();
        this.state = {
            username: "zds",
            age: 10
        }
    }
    render() {
        return (
            <div>
                username:<input
                    type="text"
                    name="username"
                    value={this.state.username} /><br />
                age:<input
                    type="text"
                    name="age"
                    value={this.state.age} />
            </div>
        )
    }
}
複製程式碼

結果可以從如下圖中看出:

16447283a25f3226?imageslim

  • 輸入框沒有繫結onChange事件無法修改輸入框中的值
  • 會觸發react警告

非受控元件

  • 非受控元件即不受狀態的控制,獲取資料就是相當於操作DOM。
  • 非受控元件的好處是很容易和第三方元件結合。

獲取輸入框中的值的兩種方法

  • ref 功能是一樣,只是寫法不一樣,可以讓我們操作DOM

第一種方式是函式

  • 在虛擬DOM節點上使用ref,並使用函式,將函式的引數掛載到例項的屬性上
handleSubmit = (e) => {
    // 阻止原生預設事件的觸發
    e.preventDefault();
    console.log(this.username.value);
}
render() {
    return (
        <form onSubmit={this.handleSubmit}>
            {/* 將真實的DOM,username是輸入框中輸入的值賦值給元件例項上
                這樣,在頁面表單提交的時候就可以通過this.username.value獲取到輸入框輸入的值
            */}
            使用者名稱<input
                name="username"
                type="text"
                ref={username=>this.username=username}
            /><br />
        </form>
    )
}
複製程式碼

現在我們來看看第一種非受控方式是如何獲取輸入框中的值的:

16447290677b2cb6?imageslim

第二種方式:通過建構函式宣告的方式

  • react 16.3新語法
  • 例項的建構函式constructor這建立一個引用
  • 在虛擬DOM節點上宣告一個ref屬性,並且將建立好的引用賦值給這個ref屬性
  • react會自動將輸入框中輸入的值放在例項的second屬性上
constructor(){
    super();
    // 在建構函式中建立一個引用
    this.second=React.createRef();
}
handleSubmit = (e) => {
    // 阻止原生預設事件的觸發
    e.preventDefault();
    console.log(this.second.current.value);
}
render() {
    return (
        <form onSubmit={this.handleSubmit}>
            {/* 自動將輸入框中輸入的值放在例項的second屬性上 */}
            密碼<input
                name="password"
                type="text"
                ref={this.second}
            /><br />
        </form>
    )
}
複製程式碼

現在我們來看看第二種非受控方式是如何獲取輸入框中的值的:

16447295019defa1?imageslim

好了,react關於表單的受控元件和非受控元件就先整理到這裡,有問題的話,歡迎大家留言溝通!

作者:tenor

原文釋出時間:2018年06月29日
本文來源掘金如需轉載請緊急聯絡作者


相關文章