2016-08-03 69 views
2

我一直在研究反應示例,​​並且一直在構建一些組件。現在我覺得我正在碰到一個基本的「Brain Fart」,關於組件結構和嵌套。將JSX傳遞給組件vs dangerouslySetInnerHTML

什麼後我:

與可選的標籤和說明文字輸入組件。

我有什麼權利現在:(其中不工作)

Input.js

//...// 
var MyInput = React.createClass({ 

render: function() { 

    //...// 

    var helpText = null; 

    if(typeof this.props.helpText !== 'undefined'){ 
     helpText = <p className="help-block" > {this.props.helpText} </p>; 
    } 

    return (
     <div className={ className }> 
     <MyLabel showLabel={ this.props.showLabel} htmlFor={ this.props.name }> 
      { this.props.title } 
     </MyLabel> 
     <input 
      type={ this.props.type || 'text' } 
      name={ this.props.name } 
      onChange={ this.changeValue } 
      value={ this.getValue() } 
      checked={ this.props.type === 'checkbox' && this.getValue() ? 'checked' : null } 
      placeholder={ this.props.title } 
     /> 
      <span className='validation-error'>{ errorMessage }</span> 
      {helpText} 
     </div> 
    ); 
    } 
}); 

module.exports = MyInput; 

LoginForm.js

//...// 

var LoginForm = React.createClass({ 

    // ... // 

    render: function() { 
     return (
      <Form className=" col-sm-11 col-lg-10 block-center loginFrm" > 

       <div className="row"> 
        <FrmInput value ="" 
          name="username" 
          title="Username" 
          className="col-sm-5" 
          showLabel={false} 
          helpText= { <span> Help text with <a href="#"> link </a> </span>} 
          required /> 
        <FrmInput value ="" 
          type="password" 
          name="password" 
          title="Password" 
          className="col-sm-5" 
          showLabel={false} 
          required /> 

        <button type="submit" 
         className="btn btn-default input-sm " 
         > 
         Sign In 
        </button> 

       </div> 

       <div className="row"> 
        <div className="pull-right" > 
         <FrmCheckbox name="rememberMe" 
          title="Remember Me" 
         /> 
        </div> 
       </div> 

      </Form> 
     ); 
    }, 

}); 

module.exports = LoginForm; 

使標籤可選很容易。我在<MyInput/>組件上使用BOOL showLabel屬性並將其傳遞給MyLabel組件。假設showLabel爲TRUE,因此將顯示標籤,除非您將showLabel設置爲false,如上所示(然後<MyLabel/>僅返回NULL)。

我首先嚐試了一個類似的方法,使用<help/>組件在<MyInput/>之內添加可選的幫助文本。一切工作,直到我在幫助文本中添加一個鏈接。研究發現dangerouslySetInnerHTML是將HTML內容傳遞到組件的一種手段。在進行測試時,我也發現上面的代碼似乎也可以工作,儘管我並沒有完全銷售這種方法的原因和方式。

總之,我只是將JSX對象傳遞到我的組件進行渲染。裏面<Form>(從LoginForm.js)的<FrmInput/>組件上有一個名爲helpText設置屬性如下

helpText= { <span> Help text with <a href="#"> link </a> </span> } 

<MyInput/>組件內我測試/監聽helpText屬性,並將其設置爲可變的時候發現(再次JSX包裝)

var helpText = null; 

if(typeof this.props.helpText !== 'undefined'){ 
    helpText = <p className="help-block" > {this.props.helpText} </p>; 
} 

然後在Render方法我有{ helpText }

總而言之它看起來像我只是通過JavaScript對象(通過JSX),直到最終的渲染方法。我沒有看到上面在教程或文檔中使用過,所以我只是在尋找專業意見。

是上述「良好」的做法或如何更好地處理。

+1

你這樣做的方式是一個好方法。避免「危險的SetInnerHTML」(顧名思義),因爲如果你不小心,它可以打開你的HTML注入攻擊。它也不會讓你傳遞具有自己的事件處理等的內容。你使用的JSX方法意味着任何人傳遞給你'helpText'實際上可以通過事件處理(單擊事件或其他)來傳遞複雜的組件。 – Brandon

回答

2

您的方法沒有任何「錯誤」。一些建議可以幫助流線化。

您可以縮短這個塊一個簡單的內聯三元:

var helpText = null; 

if(typeof this.props.helpText !== 'undefined'){ 
    helpText = <p className="help-block" > {this.props.helpText} </p>; 
} 

您可以刪除上面和你的渲染代替{helpText}

{ this.props.helpText ? this.props.helpText : null } 

在表單輸入刪除內聯幫助文件的HTML並移動到JSX的parens變量。

const helpTextContent = (<span> Help text with <a href="#"> link </a> </span>); 

隨即開始:helpText = { helpTextContent }

最後,如果你使用ES6你可以用下面的語法使用道具那麼麻煩,使:

let { helpText, someOtherProp, anotherProp } = this.props;

然後,你可以參考helpTextsomeOtherProp直接沒有this.prop每次。

希望有幫助!

+0

非常感謝您的反饋。 – Nathan