2015-05-28 44 views
1

我有幾個相同的形式與驗證功能。 我想創建除驗證功能以外具有相同行爲的另一個窗體。反應js組件多態性

我嘗試爲此使用mixins,但mixins不支持方法覆蓋。

什麼方法最適合這個問題?

這是問題的例子:https://jsfiddle.net/69z2wepo/9150/

var FormMixin = { 
    validate: function() { 
     if (this.state.message !== '') { 
      this.setState({status: 'ok'}); 
     } else { 
      this.setState({status: 'error'}); 
     } 
    }, 
    getInitialState: function() { 
     return { 
      message: 'Hello123!', 
      status: '' 
     }; 
    }, 
    handleChange: function (newValue) { 
     this.setState({ 
      message: newValue 
     }); 
    }, 
    valueLink: function() { 
     return { 
      value: this.state.message, 
      requestChange: this.handleChange 
     }  
    }, 
    render: function() { 
     return (
     <div> 
      <input type = "text" valueLink = {this.valueLink()} /> 
      <button onClick={this.validate} >Validate</button> 
      <div>{this.state.status}</div> 
     </div> 
     ); 
    } 
} 

var Form = React.createClass({ 
    mixins: [FormMixin] 
}); 

var FormEmpty = React.createClass({ 
    /*validate: function() { // How to override validation 
     this.setState({status: 'ok'}); 
    },*/ 
    mixins: [FormMixin] 
}); 

var Hello = React.createClass({ 
    render: function() { 
     return (<div> 
      <Form /> 
      <Form /> 
      <Form /> 
      <FormEmpty /> 
     </div>); 
    } 
}); 

React.render(<Hello />, document.getElementById('container')); 

回答

-1

您可以創建一個混合工廠,需要一個驗證功能參數。

function FormMixin(validate) { 
    return { 
     validate: validate, 
     /* ... */ 
    }; 
} 

var Form = React.createClass({ 
    mixins: [FormMixin(validateMessage)] 
}); 

請注意,mixin不能覆蓋render。您最好創建一個簡單的Form組件,該組件可以接受validate支持並在您的其他表單組件中重用它。

2

混入可能不是最好的辦法,他們並不在真正的JavaScript class模型陣營0.13+可用吻合。

一種簡單的替代方法是使用從Form到可以提供自定義驗證的父組件的事件/回調(jsFiddle here)。例如:

var Form = React.createClass({ 
    propTypes: { 
     validationOverride: React.PropTypes.func 
    }, 

    validate: function() { 
     if (this.props.validationOverride) { 
      this.setState({status: this.props.validationOverride() }); 
      return; 
     } 
     if (this.state.message !== '') { 
      this.setState({status: 'ok'}); 
     } else { 
     this.setState({status: 'error'}); 
     } 
    }, 
    getInitialState: function() { 
     return { 
      message: 'Hello123!', 
      status: '' 
     }; 
    }, 
    handleChange: function (newValue) { 
     this.setState({ 
      message: newValue 
     }); 
    }, 
    valueLink: function() { 
     return { 
      value: this.state.message, 
      requestChange: this.handleChange 
     }  
    }, 
    render: function() { 
     return (
     <div> 
      <input type = "text" valueLink = {this.valueLink()} /> 
      <button onClick={this.validate} >Validate</button> 
      <div>{this.state.status}</div> 
     </div> 
     ); 
    } 
}); 

var FormEmpty = React.createClass({ 
    validate: function() { 
     // you could pass in values to this function 
     return "NOT OK!"; 
    }, 
    render: function() { 
     return <Form validationOverride={ this.validate } />;  
    } 
}); 

雖然我已經離開了一些細節(因爲它是不明確的驗證是如何去工作),你可以看到我是如何創建一個名爲FormEmpty第二類,它包含一個獨身子女,Form。它傳遞一個稱爲validationOverride的回調函數。 Form在驗證需要運行時調用(如果設置)。如果未設置,則應用標準驗證邏輯。

當然,你可以選擇這種結構使有一個基類,從來沒有驗證,它總是需要通過驗證功能。通過這種方式,你總是需要做一個父和一個基礎表單的組合來執行驗證(這將是一個非常普通的React模式)。