# Unable to return HTMLDivElement in typescript component module

**URL:** <https://forum.inductiveautomation.com/t/unable-to-return-htmldivelement-in-typescript-component-module/34392>\
**Category:** Module Development\
**Created:** [May 4, 2020, 3:16am UTC](https://forum.inductiveautomation.com/t/unable-to-return-htmldivelement-in-typescript-component-module/34392 "2020-05-04T03:16:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [May 4, 2020, 3:16am UTC](https://forum.inductiveautomation.com/t/unable-to-return-htmldivelement-in-typescript-component-module/34392/1 "2020-05-04T03:16:22Z")

</div>

I am attempting to show a WebGL renderer in a perspective component, and have been working with a test component forked off the perspective example “image” component.

I think I have made a bit of progress and the Typescript itself compiles, but when I try to return either my domElement or the container that I put it in, I get a react error saying:  
**Objects are not valid as a React child (found: [object HTMLDivElement]).rgs[]**

I am assuming this is because I need to be passing it back some type of html, as thats what it looks like in any of the examples I can find, but I would like to pass back the already created element, any ideas?

I am 100% new to Javascript and Typescript so I appreciate your patience if the answer is painfully obvious

Here is a copy of the module, and I greatly appreciate any help.

```auto
import * as React from 'react';
import { Component, ComponentMeta, ComponentProps, SizeObject } from '@inductiveautomation/perspective-client';
import { observer } from 'mobx-react';
import * as THREE from '../include/three.module.js';
import { OrbitControls } from '../include/OrbitControls.js';
import { GLTFLoader } from '../include/GLTFLoader.js';

export const COMPONENT_TYPE = "ThreeD.display.Viewer";

export interface ViewerProps {
    color: string;  
}

@observer
export class Viewer extends Component<ComponentProps, any> {
    render() {
        const container = document.createElement( 'div' );

        const camera: any = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 100 );
        const scene: any = new THREE.Scene();
        const renderer: any = new THREE.WebGLRenderer({ antialias: true });
        const controls: any = new OrbitControls( camera, renderer.domElement );
        const loader: any = new GLTFLoader();

        init();
        render();

        function init() {
            camera.position.set( - 25, 15, 15);
            let ambientLight = new THREE.AmbientLight( 0x404040 );
            let directionalLight1: any = new THREE.DirectionalLight( 0xC0C090 );
            let directionalLight2: any = new THREE.DirectionalLight( 0xC0C090 );
            directionalLight1.position.set( - 100, - 50, 100 );
            directionalLight2.position.set( 100, 50, - 100 );
            scene.add( directionalLight1 );
            scene.add( directionalLight2 );
            scene.add( ambientLight );
            loader.setPath( 'models/Trapezoid/' );
            loader.load( 'Trapezoid.glb', function ( gltf: { scene: any } ) {
                scene.add( gltf.scene );
                render();
            } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.toneMapping = THREE.ACESFilmicToneMapping;
            renderer.toneMappingExposure = 0.8;
            renderer.outputEncoding = THREE.sRGBEncoding;
            container.appendChild( renderer.domElement );
            const pmremGenerator = new THREE.PMREMGenerator( renderer );
            pmremGenerator.compileEquirectangularShader();
            controls.addEventListener( 'change', render ); 
            controls.minDistance = 2;
            controls.maxDistance = 100;
            controls.target.set( 0, 0, - 0.2 );
            controls.update();
            window.addEventListener( 'resize', onWindowResize, false );
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight );
            render();
        }

        function render() {
            renderer.render( scene, camera );
        }
        //This is presumably where the error is coming from
        return(container);
    }
}

// this is the actual thing that gets registered with the component registry
export class ViewerMeta implements ComponentMeta {

    getComponentType(): string {
        return COMPONENT_TYPE;
    }

    // the class or React Type that this component provides
    getViewClass(): React.ReactType {
        return Viewer;
    }

    getDefaultSize(): SizeObject {
        return ({
            width: 360,
            height: 360
        });
    }
}

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 4, 2020, 2:56pm UTC](https://forum.inductiveautomation.com/t/unable-to-return-htmldivelement-in-typescript-component-module/34392/2 "2020-05-04T14:56:40Z")

</div>

Disclaimer: Nothing like a React expert.

I think you want to use a ref here; see the simple example near the top of this page:

> **[Refs and the DOM – React](https://reactjs.org/docs/refs-and-the-dom.html)**
>
> A JavaScript library for building user interfaces

Your `init` and other functions should probably be top-level functions on your component.

Alternately, there are existing bindings between Three.js and React; it might be easier to wrap something like [GitHub - pmndrs/react-three-fiber: 🇨🇭 A React renderer for Three.js](https://github.com/react-spring/react-three-fiber) into a Perspective component.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [May 4, 2020, 4:11pm UTC](https://forum.inductiveautomation.com/t/unable-to-return-htmldivelement-in-typescript-component-module/34392/3 "2020-05-04T16:11:57Z")

</div>

Thank you Paul!

Refs definitely look like what I need for this example, but I can also see where the react-three-fiber library would accomplish what I want easier.

This has been quite the learning experience, considering I started fooling with JavaScript like 2 days ago hahaha
