REACT:我们如何将外部库用作脚本、类或功能组件?是否可以?

IT技术 javascript reactjs
2021-05-27 12:08:18

你好,比你阅读这个问题!

我有一个用例,我必须加载 TIFF 图像。

然后我研究了如何使用这个库:https : //github.com/seikichi/tiff.js

此外,还有一个很好的使用示例,感谢@K3N Display Existing TIFF File Using the seikichi/tiff Library

我面临的困难是尝试将之前的使用示例与 React 集成。

我尝试了以下方法:

要创建一个加载脚本并将其附加到文档的类组件:

加载TIFF.js

import React from 'react';

class LoadTIFF extends React.Component {
    componentWillMount() {
        const script = document.createElement("script");

        script.src = "https://cdn.rawgit.com/seikichi/tiff.js/master/tiff.min.js";
        script.async = true;

        document.body.appendChild(script);
    }

    render() {
        return (
            document.querySelector("input").onchange = function () {

                // convert File blob to ArrayBuffer using a FileReader
                var fileReader = new FileReader();

                fileReader.onload = function () {                     // file is now ArrayBuffer:
                    var tiff = new Tiff({buffer: this.result});        // parse and convert
                    var canvas = tiff.toCanvas();                      // convert to canvas
                    document.querySelector("div").appendChild(canvas); // show canvas with content
                };

                fileReader.readAsArrayBuffer(this.files[0]);         // convert selected file
            }
        );

    }
}

export {LoadTIFF};

然后我尝试从旨在显示标题和画布 Canvas.js 的父组件中使用它:

import React from 'react';
import {LoadTIFF} from "./LoadTIFF";


class Canvas extends React.Component {

    //A canvas to display images with a title

    render() {
        return (
            <div className="previewComponent">
                <div className="imgPreview">
                    {this.props.title}
                    <LoadTIFF/>
                    <canvas></canvas>
                </div>
            </div>
        )
    }
}

export {Canvas};

控制台的输出是:🙃

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
    in LoadTIFF (at Canvas.js:14)
    in div (at Canvas.js:12)
    in div (at Canvas.js:11)
    in Canvas (at CanvasHorizontalSplitterLayout.js:12)
    in div (at CanvasHorizontalSplitterLayout.js:11)
    in div (created by o)
    in o (created by t)
    in div (created by t)
    in t (at CanvasHorizontalSplitterLayout.js:10)
    in CanvasHorizontalSplitterLayout (at Caballo.js:35)
    in div (at Caballo.js:34)
    in div (created by o)
    in o (created by t)
    in div (created by t)
    in t (at Caballo.js:33)
    in main (at Caballo.js:31)
    in Caballo (created by Route)
    in Route (at Main.js:14)
    in Switch (at Main.js:12)
    in main (at Main.js:11)
    in Main (at index.js:17)
    in div (at index.js:15)
    in App (at index.js:24)
    in Router (created by BrowserRouter)
    in BrowserRouter (at index.js:23)
__stack_frame_overlay_proxy_console__ @ index.js:2178
printWarning @ warning.js:33
warning @ warning.js:57
warnOnFunctionType @ react-dom.development.js:6760
reconcileChildFibers @ react-dom.development.js:7664
reconcileChildrenAtExpirationTime @ react-dom.development.js:7756
reconcileChildren @ react-dom.development.js:7747
finishClassComponent @ react-dom.development.js:7881
updateClassComponent @ react-dom.development.js:7850
beginWork @ react-dom.development.js:8225
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
./src/index.js @ index.js:22
__webpack_require__ @ bootstrap 5c657e191a78fa604491:678
fn @ bootstrap 5c657e191a78fa604491:88
0 @ index.js:23
__webpack_require__ @ bootstrap 5c657e191a78fa604491:678
./node_modules/ansi-regex/index.js.module.exports @ bootstrap 5c657e191a78fa604491:724
(anonymous) @ bootstrap 5c657e191a78fa604491:724

请问你能帮帮我吗?🙃

我也读过:

将脚本标签添加到 React/JSX

谢谢您的帮助!

编辑1:

感谢@Dragoş Paul Marinescu,特别是@Boy With Silver Wings 😉😉😉 我已经在一个新的 React 应用程序中尝试了@Boy With Silver Wings 的例子,你可以在这里看到:https : //github.com/YoneMoreno/ReadTiffReactApp

控制台输出如下:

./src/App.js
  Line 14:  Unexpected use of 'event'  no-restricted-globals
  Line 16:  'Tiff' is not defined      no-undef

Search for the keywords to learn more about each error.
This error occurred during the build time and cannot be dismissed.

关于事件用法,看起来我们不能将它用作全局变量,因此应该从函数的props事件中使用它Unexpected use of 'event' no-restricted-globals when using event.target.id to get id从绑定(这个)

所以我们应该将事件作为props传递给 onChange:

onChange(event) {
        const canvasNode = this.canvas;
        const fileReader = new FileReader();

        fileReader.readAsArrayBuffer(event.target.files[0]);
        fileReader.onload = function () {
            const tiff = new Tiff({
                buffer: this.result
            });
            const canvas = tiff.toCanvas();
            canvasNode.appendChild(canvas);
        };

    }

对于第二个问题,看起来需要明确声明为全局:

我的 react-google-maps 脚本无法加载

通过这两个更改,它运行良好。😉

1个回答

在 onChange 处理程序中加载函数并将相应的 html 放入 render() 方法中:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
  }
  onChange(file) {
    const canvasNode = this.canvas;
    const fileReader = new FileReader();
    
    fileReader.readAsArrayBuffer(event.target.files[0]);
    fileReader.onload = function() {
      const tiff = new Tiff({
        buffer: this.result
      });
      const canvas = tiff.toCanvas();
      canvasNode.appendChild(canvas);
    };
  
  }
  render() {
    return ( 
      <div>
        <label>
         Select TIFF file:
         <input type="file" onChange={this.onChange} />
        </label>
        <span ref={(canvas)=>this.canvas=canvas}/>
      </div>
    );
  }
}

ReactDOM.render( < App / > , document.getElementById("root"));
<script src="https://cdn.rawgit.com/seikichi/tiff.js/master/tiff.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

ref如果需要,我们正在使用React 推荐的从 DOM 中选择节点的方法。