如何使用leader-line(外部javascript库)做出反应?

时间:2018-05-29 16:53:21

标签: javascript reactjs jsx

我想在我的React网络项目中使用leader-line。它是一个外部JavaScript库,但我不知道如何使用JSX语法将其集成到项目中。
例如,its documentation告诉我们一般实现:

HTML

<div id="start">start</div>
<div id="end">end</div>

的Javascript

// Add new leader line from `start` to `end` (HTML/SVG elements, basically).
new LeaderLine(
  document.getElementById('start'),
  document.getElementById('end')
);

我应该怎么写JSX文件?
我试着在下面写,但失败了。

import React, { Component } from 'react';
import LeaderLine from 'leader-line'

class Page extends Component {

  constructor(props) {
    super(props);
  }

  componentDidMount() {
    new LeaderLine(document.getElementById('start'),
                   document.getElementById('end'));
  }

  render() {
    return (
      <div className="Page">
        <div id="start"></div>
        <div id="end"></div>
      </div>
    )
  }
}

export default Page;

This is the npm package page of leader-line.

4 个答案:

答案 0 :(得分:1)

import LeaderLine from 'leader-line';

添加leader-line.min.js(末尾)

if (module && module.exports) { module.exports = LeaderLine }

答案 1 :(得分:0)

我制作了一个小的原型来说明如何实现。

class Line extends React.Component {

  componentDidMount () {
     this.waitWhenRefIsReady();
    // scroll and resize listeners could be assigned here
  }

  componentWillUnmount () {
    if(this.timer) {
      clearInterval(this.timer);
    }
  }

  shouldComponentUpdate () {
    setTimeout(() => {
      // skip current even loop and wait
      // the end of parent's render call
      if(this.line) {
        this.line.position();
      }
    }, 0);
    // you should disable react render at all
    return false;
  }

  waitWhenRefIsReady () {
    // refs are generated via mutations - wait for them
    this.timer = setInterval(() => {
      if(this.props.start.current) {
        clearInterval(this.timer);
        this.drawLine();
      }
    }, 5);
  }

  drawLine () {
    const {start, end} = this.props;
    this.line = new LeaderLine(start.current, end.current);
  }

  render () {
    return null;
  }
}

class App extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      left: 0,
    };

    this.myRef1 = React.createRef();
    this.myRef2 = React.createRef();
  }

  componentDidMount() {
    this.animateLine();
  }

  animateLine() {
    setInterval(() => {
      const limit = 200;
      const {left} = this.state;
      const x = ((left % limit) + limit) % limit;
      this.setState({left: x + 10});
    }, 1000);
  }

  render () {
    const {left} = this.state;
    const {myRef1, myRef2} = this;

    return <div className="container">
        <Line 
          start={this.myRef1} 
          end={this.myRef2} />
        <div 
          id="start"
          ref={this.myRef1}
          style={{
            left: `${left}px`
          }}></div>
        <div
          id="end"
          ref={this.myRef2}></div>
      </div>
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

Leader Line + React JSX simple prototype

答案 2 :(得分:0)

有关如何将Leaderline集成到您的react项目中的信息,请参见以下线程:

https://github.com/anseki/leader-line/issues/8#issuecomment-370147614

总而言之, 你不能做 import LeaderLine from 'leader-line'; 导入LeaderLine,因为它还不是ES2015模块!

类似于@shilpa指出的那样, 您可以调整webpack配置以包含-

rules: [
{
        test: require('path').resolve(__dirname, 'node_modules/leader-line/'),
        use: [{
          loader: 'skeleton-loader',
          options: {procedure: content => `${content}export default LeaderLine`}
        }]
      }

然后在componentDidMount内部,您可以

new LeaderLine(document.getElementById('start'),
               document.getElementById('end'));

答案 3 :(得分:0)

根据您尝试使用 leader-line 实现的目标,您可能会发现使用 react-xarrows 也可以实现它。

https://www.npmjs.com/package/react-xarrows

React-xarrows 可以更轻松地集成到 React 应用程序中(如果您愿意,甚至可以使用 DOM 标识符而不是 React Refs)。

查看此示例代码(直接取自上面的链接),显示用法。

import React, { useRef } from "react";
import Xarrow from "react-xarrows";
 
const boxStyle = {
  border: "grey solid 2px",
  borderRadius: "10px",
  padding: "5px",
};
 
function SimpleExample() {
  const box1Ref = useRef(null);
  return (
    <div
      style={{ display: "flex", justifyContent: "space-evenly", width: "100%" }}
    >
      <div ref={box1Ref} style={boxStyle}>
        hey
      </div>
      <p id="elem2" style={boxStyle}>
        hey2
      </p>
      <Xarrow
        start={box1Ref} //can be react ref
        end="elem2" //or an id
      />
    </div>
  );
}