【问题标题】:Separating HTML to be rendered in React.js分离要在 React.js 中呈现的 HTML
【发布时间】:2016-03-13 15:04:24
【问题描述】:

我正在评估将 react.js 添加到我们即将开始的新 Web 项目中。到目前为止,我很喜欢以数据为中心的方法(感觉有点像 MVVM,因为通过更改对象的数据/状态来间接更新视图,然后视图知道代表新状态)。我有一些顾虑,其中一个我想在这里得到一些反馈,因为我正在尝试为这个项目的编码制定一套标准。

我想建立一个模式/规范,我们尝试以一种被调用和明确的方式声明我们的视觉输出/HTML。我觉得要使维护变得足够容易,您需要能够浏览这些 JSX 文件之一(我依赖 JSX)并很快看到基本输出将是什么。我还希望维护或标记与用于构建它的任何逻辑尽可能不同。

所以我一直在尝试将条件标记“块”拆分为渲染方法内的变量 - 在 return 语句之前 - 然后将它们内联到主标记中。我希望我可以在任何我想要的地方使用 JSX 标记混合技巧(呃,显然是我的名字......仍然不确定所有这些新概念的词典),就像这样:

var sIcon = (<i className='alert-success'></i>);

然后,类似:

<input type='tel' id="userPhone" onChange={this._handleInputChange('userPhone')} />{sIcon}

所以我希望使用“(....)”来创建内联 HTML 并将其存储在一个变量中(因为它具有在 IDE 中被格式化为 HTML 并且更突出的优点),然后使用大括号输出它。对我来说,更清楚的是这是输出,我更喜欢它而不是“React.DOM.div”等。根本没有渲染任何东西,但是,它只是在渲染时完全忽略了“{sIcon}”。

这可能吗?我只是在破坏它的语法吗?

或者其他人是否设计了另一种方法来在我应该尝试的 react 组件中实现更大的 HTML/逻辑分离?

当我在渲染方法中声明一个变量时特别失败,但是将它初始化为 null 然后 有条件地 稍后尝试设置它。所以简单地用 JSX 声明一个变量然后引用它就可以了,但是声明一个没有值的变量然后尝试将 JSX 分配给它会失败:

  var authorizedBlock = "";
  var sessionIdBlock = "";
  var eventCountBlock = "";
  var sIcon = "";

  var tempIcon = <i className='fa fa-check-square-o' />;
  var tempIcon2;

  if (this.state.loginAttempted) {
     if (this.state.loginSuccessful) {
        authorizedBlock = React.DOM.div (null, "Success! Ye be logged in.");
        sessionIdBlock = React.DOM.div (null, "SessionId: " + this.state.sessionId);
        eventCountBlock = React.DOM.div(null, "Your events: " + this.state.userEventCount);
        tempIcon2 = <i className='fa fa-check-square-o' />;
     }
  };

  return (
  <div id='loginContainer'>
     <div className='row'>
        <div className='col-md-2'>
           Phone:
        </div>
        <div className='col-md-2'>
           <div>
              <input type='tel' id="userPhone" onChange={this._handleInputChange('userPhone') } />
              {tempIcon}{tempIcon2}
           </div>
           {attemptedBlock}
        </div>
        <div className='col-md-1'>
           <button onClick={this._requestCode} >Get code</button>
        </div>
     </div>
</div>);

请注意,这里的 HTML 格式可能不是完全正确的;这是一个部分 sn-p,我不想包含整个喇叭文件,所以请原谅任何复制/粘贴错误。但这里的重点是,在上面的代码中,tempIcon 会出现在输出中,而tempIcon2 不会。

【问题讨论】:

  • 这是一个不错的项目wix.github.io/react-templates
  • 您是否尝试从您的render() 返回超过 1 个元素? React 目前只能返回 1 个节点,所以在你的 return 中包装任何东西都会使它工作。 var sIcon = (&lt;p&gt;hej&lt;/p&gt;); return ( &lt;div id="yo"&gt;{sIcon}&lt;/div&gt; );
  • @Hitmands 谢谢,我喜欢它的表面。当然,您必须立即开始想知道您想要将多少个框架叠加在一起,以及有多少不同的地方来维护代码,但这确实实现了我的要求。我会玩这个,但我想我更喜欢标记但内联的东西。
  • @limelights 谢谢,但这几乎就是我正在做的 - 我只从“渲染”返回一个元素,我的变量只是嵌入在一个包含我包含的 html snippter 的 div 中(抱歉,我明白那是多么令人困惑)。如果我使用“React.DOM.div”创建其他变量,则使用该语法。这可能是因为我从来没有打电话给React.DOM.div它没有在输出中结束,来吧。但是不知道React.DOM上的方法能不能用??
  • 如果您使用的是React.DOM api,那么您需要将变量作为子属性传递。

标签: javascript reactjs react-jsx jsx


【解决方案1】:

因为 JSX 只不过是专门编译的 Javascript,所以将 JSX 保存到 sIcon 变量,然后使用 {sIcon} 输出它应该可以正常工作。确保您在 render() 中声明变量,而不是在实际的 return 语句中。同样在您提供的示例中,只有空的 &lt;i&gt;&lt;/i&gt; 标签,所以无论如何都不会显示 - 在这些标签之间添加一些数据,然后看看你得到了什么。

Working jsFiddle of that

即使您现在知道自己可以做到这一点,但问题仍然存在 - 应该您吗?我会回答“不”。如果您发现自己的 JSX 确实值得与其他 JSX 分开,那么您应该为该 JSX 创建一个单独的子组件。您可以将所需的任何数据从父组件传递到子组件。然后,您将在您的父级中拥有一个明确命名的组件,使代码更具可读性和可维护性。

例如,您可以将 JSX 保存到一个名为 &lt;Message /&gt; 的新子组件中,并将一些数据传递给它,然后它会呈现这些数据。例如,您可以为父级设置这样的内容:

var App = React.createClass({
    render: function() {
        var customData = 'Hello there'; //should come from props or state
        return (<div>
                  <p>Here is some text from the parent</p>
                            <Message data={customData} />
                </div>);
    }
});

然后你可以渲染任何你想要的信息,例如:

var Message = React.createClass({
    render: function() {
        return <i className='alert-success'>{this.props.data}</i>;
    }
});

jsFiddle

很明显,在这个例子中,JSX 的数量是如此之少,以至于这看起来有点矫枉过正。但是,一旦您的项目开始扩展,效果就会非常好。请记住,您的子组件也可以有子组件,并且可以从那里继续分支。你会开始发现你的很多组件在所有地方都是可重用的,这意味着你编写的 JSX 比其他情况下要少,而且你的 JSX 变成了这棵非常易于阅读且结构良好的节点树。

一旦您对 JSX 非常熟悉,您最终将需要某种架构模式来处理任何远程复杂的应用程序。你会想看看一些Flux 的实现。我个人使用redux(技术上不是 Flux)并强烈推荐它。 Flux 的东西有一个不错的学习曲线,但是一旦全部点击,就可以理解为什么这种类型的模式与 React 配合得如此好。 Redux 的创建者here 有一个很棒的视频系列。

【讨论】:

  • 你的分数很好。我意识到 i 标记实际上不会显示,因此为了消除该变量,我嵌入了一些内容(以防它因为它不可见而没有被渲染),但它仍然没有为我渲染。在实践中,是的,我已经觉得我正在测试的这个小部件足够复杂,可以保证额外的组件,但我仍然很想看看这个语法是如何工作的。有没有机会我可以强迫你敲出一个 js fiddle 来展示这个概念?我就是看不懂。
  • 我编辑了我的答案,使其更加彻底,并为您提供两种情况的 jsFiddles。
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 2016-10-26
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
相关资源
最近更新 更多