我正在评估将 react.js 添加到我们即将开始的新 Web 项目中。到目前为止,我喜欢以数据为中心的方法(感觉有点像 MVVM,因为它通过更改对象的数据/状态间接更新 View ,然后 View 知道代表该新状态)。我有一些顾虑,其中一个我想在这里得到一些反馈,因为我正在尝试为这个项目的编码制定一套标准。
我想谈谈一种模式/规范,在这种模式/规范中,我们尝试以明确的方式声明我们的视觉输出/HTML。我觉得要使它足够容易维护,您需要能够浏览这些 JSX 文件之一(我依赖 JSX)并查看基本输出将是相当快的。我还希望维护或标记尽可能独立于用于构建它的任何逻辑。
所以我一直在尝试将条件标记“ block ”拆分为渲染方法内的变量——在返回语句之前——然后将它们内联到主标记内。我希望我可以在任何我想使用的地方使用 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/逻辑分离?
当我在 render 方法中声明一个变量时,它特别失败,但将其初始化为 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 格式可能不完全正确;这是一个部分片段,我不想包含整个喇叭文件,所以请原谅任何复制/粘贴错误。但这里的要点是,根据上面的代码,tempIcon
将显示在输出中,但 tempIcon2
不会。
最佳答案
因为 JSX 只不过是专门编译的 Javascript,将你的 JSX 保存到 sIcon
变量,然后用 {sIcon}
输出它应该实际工作。确保在 render()
内声明变量但不在实际 return
内陈述。同样在您提供的示例中,只有空的 <i></i>
标签,所以无论如何都不会显示 - 在这些标签之间添加一些数据,然后看看你得到了什么。
即使您现在知道您可以做到这一点,问题仍然存在 - 应该吗?我会回答“不”。如果你发现自己的 JSX 确实值得与其他 JSX 分开,你应该为那个 JSX 创建一个单独的子组件。您可以将父组件所需的任何数据传递给子组件。然后,您的父组件中将有一个明确命名的组件,使代码更具可读性和可维护性。
例如,您可以将 JSX 保存到名为 <Message />
的新子组件中并将一些数据传递给它,然后它会呈现这些数据。例如,您可以为 parent 准备这样的东西:
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>;
}
});
很明显,在这个例子中,JSX 的数量太少了,这看起来有点矫枉过正。但是,一旦您的项目开始扩展,效果就会非常好。请记住,您的子组件也可以有子组件,并且可以从那里继续分支。你会开始发现你的很多组件在任何地方都是可重用的,这意味着你编写的 JSX 比其他情况下少,并且你的 JSX 变成了这棵人类可读且结构良好的节点树。
一旦您对 JSX 非常熟悉,您最终将需要某种架构模式来处理任何远程复杂的应用程序。你会想看看一些 Flux实现。我个人使用 redux (这在技术上不是 Flux)并强烈推荐它。 Flux 的东西有一个不错的学习曲线,但是一旦全部点击就可以理解为什么这种模式与 React 配合得如此好。 Redux 的创建者有一个很棒的视频系列 here .
关于javascript - 分离要在 React.js 中呈现的 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34160207/