1. 程式人生 > >React官方文件--Forms

React官方文件--Forms

Forms

表單元件,比如:<input><textarea><option>和基本的元件不同,因為表單元件是需要使用者進行互動的。這些元件提供了介面,用來更容易的管理表單來響應使用者的互動。
有兩種形式的表單元件
1. Controlled Components
2. Uncontrolled Components

Controlled Components

一個受控表單元件提供一個value屬性,一個受控表單元件不會維持其內部自己的狀態,元件只根據props進行渲染。

render() {
    return (
        <input
            type
="text" value="Hello!" /> ) }

如果你試圖去執行這裡例子,會發現輸入框裡的內容不會隨著輸入而改變。因為你聲明瞭這個元件的value值,為了更新value作為使用者輸入的響應,需要新增onChange事件來儲存新的值,然後傳遞這個值給value屬性。

class Form 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) { console.log("Text field value is : " + this.state.value); } render() { return
( <div> <input type="text" placeholder="Hello!" value={this.state.value} onChange={this.handleChange}/> <button onClick={this.handleSubmit}> Submit </button> </div> ) } } ReactDOM.render( <Form />, document.getElementById("root") );

在這個例子中,我們接受使用者提供的值,來更新value 的值,這種方法使得繼承介面或者進行表單驗證變得很方便

handleChange(event) {
    this.setState({
        value: event.target.value.substr(0, 14)
    });
}

Checkboxes和RadioButton存在的潛在問題

在使用React來監聽checkbox或者radio的事件的時候,React監聽一個click的瀏覽器事件來宣告一個onChange事件,在大部分情況下這樣是沒有什麼問題的,除非當你呼叫了preventDefault()在change的事件處理函式裡面,preventDefault會停止瀏覽器在視覺上更新輸入,即使checked的值已經改變了,這個問題可以通過不呼叫preventDefault或者將切換checked的值放在setTimeout中執行來解決。

非受控元件

不提供value屬性的表單元件稱為非受控元件。下面的例子渲染了一個<input>來控制一個空的值,任何使用者輸入的值會立刻影響到渲染的元素。
一個非受控元件管理他自己的狀態。

render() {
    return <input type="text" />
}

如果你希望監聽這個元件的值的更新,你需要使用onChange事件來監聽,就像受控元件一樣,但是不能給元件傳遞任何值。

class Form 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("Text field value is : " + this.state.value);
    }

    render() {
        return (
            <div>
                <input 
                    type="text"
                    placeholder="Hello!"
                    onChange={this.handleChange} />
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        );
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
)

當這個例子輸入value的時候,我們可以通過handleSubmit()來讀取,非受控表單元件不能夠請求,你需要完整的onChange事件處理來取代讀取value

預設值

使用一個非空的value來初始化一個非受控元件,你可以使用一個defaultValue屬性

render() {
    return <input type="text" defaultValue="Hello" />
}

同樣地,<input type="checkbox"><input type="radio">支援defaultChecked然後<select>支援defaultValue

互動屬性

表單元件支援一系列的props會通過使用者互動影響元件。
1. value,是<input><textarea>支援的元件。
2. checked,是<input>元件的checkboxradio支援的
3. selected,是<option>元件支援的。
在HTML中,<textarea>的值是通過子元素來設定的,在React中,需要使用value來替代
表單元件允許通過onChange屬性的回撥函式來監聽修改,onChange屬性通過瀏覽器和使用者互動的響應。

進階技術

為什麼使用受控元件

使用類似<input>的表單元件是和傳統的HTML不相同的。

<input type="text" name="title" value="Untitle">

上面的程式碼渲染初始化了一個value為Untitle。當用戶更新輸入的時候,這個節點的value屬性也會改變,然而使用node.getAttribute('value')仍然會返回初始化的時候的值:Untitled
與HTML不同的是,React元件必須一致保持其狀態,也就是自從渲染之後,value的值一直保持為Untitled

Why Textarea Value

在HTML,<textarea>的值應該是其子元素的值。

<textarea name="description">This is the description.</textarea>

在HTML中,很容易允許開發人員提供多行的值,然而,在React中,我們不能夠設定多行的字串,如果要換行的話需要使用\n,在有value和defaultValue的時候,因為這個原因,你不需要使用子元素來設定<textarea>的值。

<textarea name="description" value="This is a description.">

Why Select Value

option<select>中是用selected屬性來進行判斷選擇的,但是在React的元件中,是使用value屬性的。

<select value="B">
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
</select>

使用非受控元件的話,這裡需要使用defaultValue

受控輸入框

class Form 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('Text field value is: ' + this.state.value);
    }

    render() {
        return (
            <div>
                <input
                type="text"
                placeholder="edit me"
                value={this.state.value}
                onChange={this.handleChange}
                />
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        );
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById('root')
);

受控文字區元件

class Form 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("Textarea value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <textarea
                    name="description"
                    value={this.state.value}
                    onChange={this.handleChange}
                />
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

受控下拉列表

class Form 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("Select value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <select value={this.state.value} onChange={this.handleChange}>
                    <option value="A">Apple</option>
                    <option value="B">Banana</option>
                    <option value="C">Cranberry</option>
                </select>
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

非受控單選按鈕

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: "B"
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(event) {
        alert("Radio button value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <label>
                    <input type="radio" name="choice" value="A" onChange={this.handleChange}/>
                    Option A
                </label>
                <label>
                    <input type="radio" name="choice" value="B" onChange={this.handleChange}/>
                    Option B
                </label>
                <label>
                    <input type="radio" defaultChecked={true} name="choice" value="C" onChange={this.handleChange}/>
                    Option C
                </label>
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

非受控複選框

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            checked: {
                'A': false,
                'B': true,
                'C': false
            }
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        const value = event.target.value;

        const checked = Object.assign({}, this.state.checked);
        if (!checked[value]) {
            checked[value] = true;
        } else {
            checked[value] = false;
        }
        this.setState({checked});
    }

    handleSubmit(event) {
        alert("Boxes checked: " + 
            (this.state.checked.A ? 'A ' : ' ') +
            (this.state.checked.B ? 'B ' : ' ') +
            (this.state.checked.C ? 'C ' : ' ')
        );
    }

    render() {
        return (
            <div>
                <label>
                    <input type="checkbox" value="A" onChange={this.handleChange} />
                    Option A
                </label>
                <label>
                    <input type="checkbox" value="B" onChange={this.handleChange} defaultChecked={true}/>
                    Option B
                </label>
                <label>
                    <input type="checkbox" value="C" onChange={this.handleChange} />
                    Option C
                </label>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);