javascript - 如何从 jQuery 到 React.js?

标签 javascript jquery reactjs

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




我已经阅读 React 好几天了。我可以理解我所看到的大部分内容,但我对自己的写作能力并不完全有信心。我一直在开发一个小型 Web 应用程序,该应用程序通过 jQuery 生成所有 html 并将元素相互附加。我想尝试用 React 重建它,因为我相信它会更快。此 JSFiddle是我正在做的事情的一个小例子。你会如何用 React 编写它?

JS:

function remove() {
    this.remove();
}

function timed_append_new_element() {
    setTimeout(function () {
        var added_content = $("<span />", {
            class: "added_content",
            text: "Click to close",
            click: remove
        });
        container.append(added_content);
    }, 3000);
}

function append_new_element() {
    var added_content = $("<span />", {
        class: "timed_added_content",
        text: "Click to close",
        click: remove
    });
    container.append(added_content);
}


var container = $("<div />", {
    class: "container"
});
var header = $("<span />", {
    class: "header",
    text: "jQuery to React.js Header"
});
var add_button = $("<button />", {
    class: "add_button",
    text: "Add Element",
    click: append_new_element
});
var timed_add_button = $("<button />", {
    class: "add_button",
    text: "Add Element in 3 seconds",
    click: timed_append_new_element
});
container.append(header);
container.append(add_button);
container.append(timed_add_button);
$("body").append(container);

最佳答案

有一些基本原则需要记住,可以帮助你构建一个好的 React 应用程序:

您的 UI 应该是数据的函数

在许多“jQuery 汤”风格的应用程序中,应用程序的业务逻辑、应用程序的数据和 UI 交互代码都混杂在一起。这使得这些类型的应用程序难以调试,尤其是难以发展。像许多现代客户端应用程序框架一样,React 强调 UI 只是数据的表示形式。如果您希望您的 UI 发生变化,您应该更改一段数据并允许框架使用的任何绑定(bind)系统为您更新 UI。

在 React 中,每个组件(理想情况下)都是两个数据的函数——传递给组件实例的属性,以及组件内部管理的状态。给定相同的属性(或“ Prop ”)和状态,组件应该以相同的方式呈现。

这可能是一个没有具体示例的抽象想法,因此在我们继续前进时请记住这一点。

不要接触 DOM

在 React 中,甚至比其他数据绑定(bind)框架更是如此,如果可能,您应该尽量不要直接操作 DOM。很多 React 的性能和复杂性特性之所以成为可能,是因为 React 使用了一个虚拟 DOM,内部有不同的算法来操作真实的 DOM。任何时候你构建一个组件,它会伸出并执行自己的 DOM 操作,你应该问问自己,是否可以使用 React 的虚拟 DOM 功能更惯用地构建相同的功能。

当然,有时你需要访问 DOM,或者你想要合并一些 jQuery 插件而不用在 React 中重建它。在这种情况下,React 会给你带来好处 component lifecycle hooks您可以使用它来确保 React 的性能不会受到太大影响(或者,在某些情况下,可以防止您的组件完全损坏)。

不操作 DOM 与上面的“UI 作为数据的函数”密切相关。

反转数据流

在大型 React 应用程序中,可能很难跟踪哪个子组件正在管理某个应用程序数据。出于这个原因,React 团队建议将数据操作逻辑放在一个中央位置。最直接的方法是将回调传递给子组件; Facebook 还开发了一个名为 Flux 的架构,它具有 its own website .

创建可组合组件

很多时候,编写一个管理多个状态或多个 UI 逻辑的大型组件可能很诱人。在可能的情况下(并在合理范围内),您应该考虑将较大的组件分解为对单个数据或 UI 逻辑进行操作的较小组件。这使得扩展和移动应用程序的各个部分变得更加容易。

当心可变数据

由于组件状态只能通过调用 this.setState 来更新。从组件内部,警惕可变数据是有帮助的。当多个函数(或组件!)可能在同一个滴答中更新可变对象时,这是双重正确的; React 可能会尝试批量更改状态,您可能会丢失更新!正如 Eliseu Monar 的评论中提到的,在改变可变对象之前考虑克隆可变对象。 React 有 immutability helpers可以提供帮助。

另一种选择是完全放弃将可变数据结构直接保持在状态中;上面提到的 Flux 模式是对这个想法的一个有趣的理解。

React 站点上有一篇很棒的文章,名为 Thinking in React它讨论了你如何将一个想法或模型转化为 React 应用程序,我强烈建议你仔细阅读它。作为一个具体的例子,让我们来看看你提供的代码。您实际上需要管理一项数据:存在于 container 中的内容列表。元素。 UI 的所有更改都可以通过对该数据的添加、删除和更改来表示。

通过应用上述原则,您的最终应用程序可能如下所示:

/** @jsx React.DOM */

var Application = React.createClass({
  getInitialState: function() {
    return {
      content: []
    };
  },

  render: function() {
    return (
      <div className="container">
        <span className="header">jQuery to React.js Header</span>
        <button className="add_button"
                onClick={this.addContent}>Add Element</button>
        <button className="add_button"
                onClick={this.timedAddContent}>Add Element in 3 Seconds</button>
        {this.state.content.map(function(content) {
          return <ContentItem content={content} removeItem={this.removeItem} />;
        }.bind(this))}
      </div>
    );
  },

  addContent: function() {
    var newItem = {className: "added_content", text: "Click to close"},
        content = this.state.content,
        newContent = React.addons.update(content, {$push: [newItem]});
    this.setState({content: newContent});
  },

  timedAddContent: function() {
    setTimeout(function() {
      var newItem = {className: "timed_added_content", text: "Click to close"},
          content = this.state.content,
          newContent = React.addons.update(content, {$push: [newItem]});
      this.setState({content: newContent});
    }.bind(this), 3000);
  },

  removeItem: function(item) {
    var content = this.state.content,
        index = content.indexOf(item);
    if (index > -1) {
      var newContent = React.addons.update(content, {$splice: [[index, 1]]});
      this.setState({content: newContent});
    }
  }
});

var ContentItem = React.createClass({
  propTypes: {
    content: React.PropTypes.object.isRequired,
    removeItem: React.PropTypes.func.isRequired
  },

  render: function() {
    return <span className={this.props.content.className}
                 onClick={this.onRemove}>{this.props.content.text}</span>;
  },

  onRemove: function() {
    this.props.removeItem(this.props.content);
  }
});

React.renderComponent(<Application />, document.body);

您可以在 this JSFiddle 中看到正在运行的代码:http://jsfiddle.net/BinaryMuse/D59yP/

该应用程序由两个组件组成:一个名为 Application 的顶级组件。 ,它管理(在其状态下)一个名为 content 的数组,以及一个名为 ContentItem 的组件,表示该数组中单个项目的 UI 和行为。 Applicationrender方法返回 ContentItem内容数组中每个项目的元素。

需要注意的一件事是管理 content 中的值的所有逻辑。数组在 Application 中处理成分; ContentItem组件传递了对 Application 的引用的 removeItem方法,其中ContentItem单击时委托(delegate)。这将所有用于操作状态的逻辑保留在顶级组件中。

关于javascript - 如何从 jQuery 到 React.js?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23585765/

相关文章:

javascript - 在 Alexa Skill 中输入多个单词

javascript - 通过 Id 调用来遍历数组元素

javascript - 在 bootstrap 弹出窗口中选择的 jquery 不起作用

react : useMemo hook fixed my infinite rerender issue instead of useEffect

javascript - 将垂直滚动位置绑定(bind)到计​​数器

javascript - 使用 V-FOR VUE 时图像未显示

javascript - 为什么使用 Jquery 我的变量不会出现在文本框中?

javascript - 随机几秒后更改框颜色

javascript - 为什么我们需要为 JSX 回调绑定(bind) 'this'

javascript - 使用 React 添加和删除 CSS 类