2016-08-03 71 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