分离要在React.js中呈现的HTML

时间:2015-12-08 15:51:31

标签: javascript reactjs react-jsx jsx

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

我想找到一个模式/规范,我们尝试以这样的方式声明我们的视觉输出/ HTML,以便它被调出并显式化。我觉得要让这很容易维护你需要能够浏览其中一个JSX文件(我依赖于JSX)并且看看基本输出会很快。我也希望维护或标记尽可能与构建它的逻辑完全不同。

因此,我一直试图将有条件的标记分割出来?' chunks'到render方法中的变量 - 在return语句之前 - 然后在主标记内嵌入它们。我希望我可以在任何地方使用JSX标记混合技巧(呃,我的名字显然......仍然不确定所有这些新概念的词典),如下所示:

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

然后,类似的事情:

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

所以我希望能够使用&#39; (....)&#39;创建内联HTML并将其存储在变量中(因为它具有在IDE中格式化为HTML并且更加突出的优点),然后使用大括号输出它。对我而言,更清楚的是这是输出,我更喜欢它,并且它更喜欢#34; React.DOM.div&#34;等等。没有任何东西可以渲染,但是,它只是忽略了&#39; { {1}}&#39;完全渲染时。

这可能吗?我只是想要它的语法吗?

或者是否有其他方式设计用于在反应组件中实现更大的HTML /逻辑分离?我应该尝试一下?

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

{sIcon}

请注意,这里的HTML可能不完全正确;它是一个部分片段,我不想包含整个鸣笛文件,所以原谅任何复制/粘贴gaffs。但重点是,鉴于上述代码, 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>); 将显示在输出中,但tempIcon不会。

1 个答案:

答案 0 :(得分:2)

因为JSX只不过是专门编译的Javascript,将JSX保存到sIcon变量,然后用{sIcon}输出它应该可以正常工作。确保在render()内声明变量,但不在实际return语句中声明。同样在您提供的示例中,只有空<i></i>标记,因此无论如何都不会显示任何内容 - 在这些标记之间添加一些数据,然后查看您获得的内容。

Working jsFiddle of that

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

例如,您可以将JSX保存到名为<Message />的新子组件中,并将一些数据传递给它,然后将其呈现。例如,您可以为父母提供类似的内容:

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将成为人工可读且结构良好的节点的树。 / p>

一旦你对JSX感到非常熟悉,你最终需要某种架构模式用于任何远程复杂的应用程序。您需要查看一些Flux实现。我个人使用redux(技术上不是Flux)并强烈推荐它。 Flux的东西有一个不错的学习曲线,但是一旦点击它就有意义为什么这种类型的模式与React一起工作得很好。 Redux的创建者here有一个很棒的视频系列。