2015-07-01 28 views
3

已經與React.js了兩天,我已經寫了我的大部分格式,如:工作後,以下(如official tutorial爲例):創建豐富的表單組件暴露值父組件

React.createClass({ 
    handleSubmit: function (event) { 
    event.preventDefault(); 
    var value = React.findDOMNode(this.refs.text).value; 
    // do something with the value 
    }, 
    render: function() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <input type="text" ref="text" defaultValue="foo" /> 
     <input type="submit" value="Save"/> 
     </form> 
    ); 
    } 
} 

不過,我發現recenctly這種方法的弱點在那裏,我不能寫在那些建立了由這樣的組件,如表格中使用豐富的形式組成:

var RichInput = React.createClass({ 
    render: function() { 
    return (
     <div className="someStyle"> 
     <input type="text" ref="text" defaultValue="foo" /> 
     </div> 
    ); 
    } 
} 

React.createClass({ 
    handleSubmit: function (event) { 
    event.preventDefault(); 
    var value = React.findDOMNode(this.refs.text).value; 
    // do something with the value 
    }, 
    render: function() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <RichInput /> 
     <input type="submit" value="Save"/> 
     </form> 
    ); 
    } 
} 

現在我想知道。通過現有資源尋找後,我發現下面的方法來克服這個限制:

var RichInput = React.createClass({ 
    render: function() { 
    return (
     <div className="someStyle"> 
     <input type="text" value="foo" onChange={this.props.callback} /> 
     </div> 
    ); 
    } 
} 

React.createClass({ 
    handleSubmit: function (event) { 
    event.preventDefault(); 
    var value = this.state.text 
    // do something with the value 
    }, 
    getInitialState() { 
    return {text: 'foo'}; 
    } 
    updateText: function(value) { 
    this.setState({text: value}); 
    } 
    render: function() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <RichInput callback={this.updateText} /> 
     <input type="submit" value="Save"/> 
     </form> 
    ); 
    } 
} 

這是規範的解決方案,編寫模塊化形式組件?我想知道這對我來說似乎有很多開銷。我需要編寫額外的功能我需要使組件處於完全狀態,這使我無法適應此解決方案。另外,我想知道性能,因爲我不需要更新每次更改的價值,但僅限於(以及在)提交表單的情況下。

一種可能性,我發現是使用:

React.findDOMNode(this.refs.rich.refs.text); 

鑑於RichInputref="rich"上定義。但是React的文檔再次表示refs不應該被認爲是傀儡API,並且可以在組件之外訪問。

+0

你也可以做'this.refs.rich.getDOMNode()value'。也不確定你的問題是什麼?你問你應該如何處理這些行爲? – knowbody

+0

這對我的示例嘗試使用時不起作用。我想知道在React中閱讀孩子的表單值是什麼規範的方法。 –

回答

1

這是我構建我的摘要Input組件的方式。我用它爲各種目的(無論何時我需要用戶輸入的東西,我想以後處理動作)(例如用ES6/7的一些引導的造型):

import React, { PropTypes, Component } from 'react'; 

export default class Input extends Component { 
    static propTypes = { 
    placeholder: PropTypes.string, 
    buttonText: PropTypes.string, 
    onButtonClick: PropTypes.func 
    } 

    constructor() { 
    super(); 

    this._handleClick = this._handleClick.bind(this); 
    this._handleKeyUp = this._handleKeyUp.bind(this); 
    } 

    render() { 
    return (
     <div className='Input'> 
     <div className='input-group'> 
      <input type='text' className='form-control' placeholder={this.props.placeholder} 
       ref='inputBox' onKeyUp={this._handleKeyUp} 
      /> 
      <span className='input-group-btn'> 
      <form onSubmit={this._handleClick}> 
       <button className='btn btn-success' type='submit'>{this.props.buttonText}</button> 
      </form> 
      </span> 
     </div> 
     </div> 
    ); 
    } 

    _handleClick(e) { 
    e.preventDefault(); 
    let value = this.refs.inputBox.getDOMNode().value; 
    this.props.onButtonClick(value); 
    value = null; 
    } 

    _handleKeyUp(e) { 
    e.preventDefault(); 
    if (e.keyCode === 13) { 
     this._handleClick(e); 
    } 
    } 
} 

然後在Parent組件您可以初始化它想:

<Input placeholder='Enter something' 
     buttonText='Submit' 
     onButtonClick={this._handleButtonClick} 
/> 

和處理_handleButtonClick

_handleMakeSearch(text) { 
    console.log(text); 
} 
1

這是一個通常的解決方案,創建非常小的組件和一個處理其子組件的所有狀態的包裝器(父組件),因爲這些子組件的狀態通常取決於其他子組件的狀態。

所以你是對的,包裝/父組件將有一個(很多)的開銷,但這樣你的「真實」組件更模塊化。

var RichInput = React.createClass({ 
    render() { 
     return (
      <div className="someStyle"> 
       <input type="text" value={this.props.value} onChange={this.props.onChange} /> 
      </div> 
     ); 
    } 
} 

React.createClass({ 
    handleSubmit: function (event) { 
     event.preventDefault(); 
     var value = this.state.value; 
     // do something with the value 
    }, 

    getInitialState() { 
     return {value: 'foo'}; 
    } 

    updateValue(value) { 
     this.setState({value}); 
    } 

    render() { 
     return (
      <form onSubmit={this.handleSubmit}> 
       <RichInput value={this.state.value} onChange={this.updateValue} /> 
       <input type="submit" value="Save"/> 
      </form> 
     ); 
    } 
} 

Here是其他問題/答案,在這裏你可以看到一個例子/使用情況。處理其子組件的所有狀態的父組件,其中每個狀態彼此依賴。也許這有助於理解這種方法的好處。