React中的第三方DOM操作

时间:2018-05-08 18:26:06

标签: jquery reactjs dom svg

我目前正在将一个传统的BackboneJS应用移植到ReactJS。该应用使用VexFlow,JavaScript音乐符号渲染引擎。我遇到的一个主要问题是VexFlow以与D3类似的方式将所有内容呈现给SVG。将D3与React结合起来有很多信息,我正在遵循使用空的React ref元素作为我的VexFlow渲染的目标的情况下的一般做法,这一切都发生在componentDidMount

export default class ScoreComponent extends React.Component {

  constructor(props) {
    super(props);
    // Create a 'ref' object, which allows us to reference the React DOM
    // element we create in the render method.
    this.scoreElem = React.createRef();
    ...
  }

  componentDidMount() {
    var score = this.score;
    var elem = this.scoreElem.current;
    score.setElem(elem).render(); // <- All VexFlow rendering happens here...
    ...
  }

  render() {
    return (
      <div className="score" id={this.props.scoreId} ref={this.scoreElem}></div>
    );
  }

}

虽然这很有效,但它让我感到很不舒服,特别是因为我还需要添加大量的jQuery代码来处理SVG元素上的用户交互(例如,单击并拖动复杂的路径对象),其中没有一个是React请注意。

所以我的问题是:我是否会走上一条会导致我被烧伤的道路?我真的很喜欢React,我很想跟Backbone说再见。我能够在一个周末轻松地移植我的大部分UI代码。我过去曾看过Angular,但看起来太复杂了,而且很自以为是。

1 个答案:

答案 0 :(得分:1)

你正朝着正确的方向前进。当您需要使用外部非反应DOM库来呈现内容时,这是可行的方法:

  1. 在构造函数中创建一个DOM元素的引用。
  2. componentDidMount()上启动插件实例,并在插件的实例上添加对插件实例的引用作为属性。这将使您能够从其他方法调用实例的方法。
  3. componentDidUpdate()中的更改进行反应。使用插件实例的引用来更新它。
  4. componentWillUnmount()中清除插件添加/预定/等等的所有内容...例如事件侦听器,超时/间隔,在React树外部创建的DOM节点,正在进行的AJAX调用等等......
  5. 在渲染中 - 不要向容器添加任何属性,因此不会在道具/状态更改时重新渲染。
  6. 注意:在React 16.3之前,标准方法是通过返回$.getJSON("menu.json") .done(function(obj) { console.log(obj.name); }); 中的false并对{{1}中的道具变化作出反应来防止重新渲染道具/状态变化}}。然而,后者是被弃用的方式,而前者将是一个建议,而不是将来的严格订单。

    此(非工作)示例基于当前VexFlow tutorial

    shouldComponentUpdate()