首页 > 解决方案 > React/NPM:如何封装组件?

问题描述

假设我有以下显示旋转立方体的工作反应应用程序。

npm create-react-app
vi src/App.js

复制粘贴以下内容:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import * as THREE from "three";
class App extends Component {
  componentDidMount() {
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    // document.body.appendChild( renderer.domElement );
    // use ref as a mount point of the Three.js scene instead of the document.body
    this.mount.appendChild( renderer.domElement );
    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    camera.position.z = 5;
    var animate = function () {
      requestAnimationFrame( animate );
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render( scene, camera );
    };
    animate();
  }
  render() {
    return (
      <div ref={ref => (this.mount = ref)} />
    )
  }
}
export default App
npm run build

瞧,旋转立方体!


但是,接下来我尝试做的是:封装旋转的立方体并创建一些下拉菜单,让我可以查看立方体或其他东西。

不过,我没有得到下拉菜单,因为我无法将 Cube 类封装在函数下方:

mport React, { Component } from "react";
import ReactDOM from "react-dom";
import * as THREE from "three";
class ICube extends Component {
  componentDidMount() {
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    // document.body.appendChild( renderer.domElement );
    // use ref as a mount point of the Three.js scene instead of the document.body
    this.mount.appendChild( renderer.domElement );
    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    camera.position.z = 5;
    var animate = function () {
      requestAnimationFrame( animate );
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render( scene, camera );
    };
    animate();
  }
  render() {
    return (
      <div ref={ref => (this.mount = ref)} />
    )
  }
}
export default function App() {
  var cube = ICube()
  return ( 
      <div ref={ref => (cube.mount = ref)} />
  )   
}

这会构建,但不会渲染。我不确定这种封装应该如何进行。有什么特别的方法可以封装这个吗?

我也尝试过创建一个:

export default class App extends Component {
  cube = ICube()
  componentDidMount() {
  }
  render() {
    return (
      <div ref={ref => (this.cube.mount = ref)} />
    )
  }
}

作为直接封装,但这不起作用。

标签: reactjs

解决方案


您不需要为此目的创建 refs。只需导入您的组件并在您的渲染函数中使用它

import React, { Component } from "react";
import ReactDOM from "react-dom";
import * as THREE from "three";
class ICube extends Component {
  componentDidMount() {
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    // document.body.appendChild( renderer.domElement );
    // use ref as a mount point of the Three.js scene instead of the document.body
    this.mount.appendChild( renderer.domElement );
    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    camera.position.z = 5;
    var animate = function () {
      requestAnimationFrame( animate );
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render( scene, camera );
    };
    animate();
  }
  render() {
    return (
      <div className"some-style-class">
         <App />
         {//some other components}
      </div>
    )
  }
}

要有条件地渲染您的形状,您可以将道具传递给您的 App 组件,例如

<App
  shape={this.state.shape} 
/>

形状类型的值可以来自您制作的下拉组件


推荐阅读