4

我正在评估将 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}在渲染时完全忽略了''。

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

还是其他人设计了另一种方法来在我应该尝试的反应组件中实现更大的 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 格式可能不是完全正确的;这是一个部分片段,我不想包含整个喇叭文件,所以请原谅任何复制/粘贴错误。但这里的重点是,给定上面的代码,tempIcon将显示在输出中,但tempIcon2不会。

4

1 回答 1

2

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

工作的jsFiddle

即使你现在知道你可以做到这一点,但问题仍然存在——你应该这样做吗?我会回答“不”。如果您发现自己的 JSX 确实值得与其他 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 变成了这棵非常易于阅读且结构良好的节点树。

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

于 2015-12-08T16:20:20.397 回答