enter image description heresorry for if the something i wrote makes you upset. this is the first time to ask question in this site. thie is the code

const canvasRef = useRef(null);
const containerSize = { width: 6.1, height: 2.4, depth: 2.6 };
const palletEx = { width: containerSize.width / 2, height: 0.2, depth: containerSize.depth };
const palletTypeA = { id: 'typeA', width: 1.1, height: 0.15, depth: 1.1 };
const [palletState, setPalletState] = useState(0);
const [pallet, setPallet] = useState(null);
const rendererRef = useRef(null);
const sceneRef = useRef(null);
const [pallets, setPallets] = useState([]);

const camera = new THREE.PerspectiveCamera(50, 1.6, 0.1, 1000);


useEffect(() => {
    const canvas = canvasRef.current;
    const container = canvas.parentElement;
    const scene = new THREE.Scene();
    sceneRef.current = scene;

    scene.background = new THREE.Color(0xFFFFFF);

    const renderer = new THREE.WebGLRenderer({
        canvas,
        antialias: true,
    });

    rendererRef.current = renderer;

    renderer.setPixelRatio(window.devicePixelRatio);

    renderer.setSize(container.clientWidth, container.clientHeight);

    const controls = new OrbitControls(camera, renderer.domElement);
    camera.position.x = -1;
    camera.position.y = 3;
    camera.position.z = 25;
    sceneRef.current.camera = camera;

    const containerCube = createCube(containerSize.width, containerSize.height, containerSize.depth);
    scene.add(containerCube);
    containerCube.position.set(0, 0, 0);

    const palletExCube = createCube(palletEx.width, palletEx.height, palletEx.depth);
    scene.add(palletExCube);
    palletExCube.position.set(0, 0, 0);

    canvas.addEventListener("onClick", onClick1);
    const addButton = document.getElementById('addButton');
    

    animate();


}, []);



const animate = function () {
    requestAnimationFrame(animate);
    rendererRef.current.render(sceneRef.current, sceneRef.current.camera);
};

接下来是方法(它将在我单击按钮时执行)

const onClick1 = () => {
    const newPallet = createCube(palletTypeA.width, palletTypeA.height, palletTypeA.depth);
    sceneRef.current.add(newPallet);
    newPallet.position.set(Math.random()*10, Math.random()*10, Math.random()*10);
    setPallets(prevPallets => [...prevPallets, newPallet]);
};

const onClick2 = () => {

    if (pallets.length > 0) {
        // Remove the last cube from the scene
        const removedPallet = pallets.pop();
        sceneRef.current.remove(removedPallet);
        // Update the cubes state
        setPallets([...pallets]);
    }
};

``

当我按下Add按钮时,我想要将托盘添加到场景中,但托盘被创建后立即消失.我希望只有当添加按钮被点击时才创建托盘,只有当按下删除按钮时才会消失.不幸的是,我不得不寻求帮助,因为我必须做出react 和Three.js,这是我完全不知道的.

推荐答案

看起来您没有正确处理Reaction组件中的状态.未在onClick1和onClick2方法中正确更新处于状态的托盘array.

在场景中添加新托盘和从场景中移除托盘后,需要调用setPallets函数来更新状态中的托盘array.您在onClick1中执行此操作,但在onClick2中直接改变托盘数组,而不调用setPallets.

try 按如下方式更新onClick2函数:

const onClick2 = () => {
    if (pallets.length > 0) {
        // Remove the last cube from the scene
        const removedPallet = pallets[pallets.length - 1];
        sceneRef.current.remove(removedPallet);
        // Update the cubes state
        setPallets(prevPallets => prevPallets.filter(pallet => pallet !== removedPallet));
    }
};

此函数将从场景和状态中删除最后一个托盘.

此外,您似乎要在画布元素上附加一个onClick事件侦听器.通常,我们会在DOM中的按钮或其他交互元素上附加单击事件.确保您的addButton和DeleteButton(如果存在)正在处理这些onClick1和onClick2函数.

以下是一种简单的方法:

useEffect(() => {
    const addButton = document.getElementById('addButton');
    const deleteButton = document.getElementById('deleteButton'); // Ensure this button exists in your DOM

    addButton.addEventListener("click", onClick1);
    deleteButton.addEventListener("click", onClick2);

    // Remember to cleanup event listeners when component unmounts
    return () => {
        addButton.removeEventListener("click", onClick1);
        deleteButton.removeEventListener("click", onClick2);
    }
}, []);

这将在组件挂载时向按钮添加Click事件侦听器,并在组件卸载时删除它们.

创建多维数据集的示例,您可以根据需要对其进行调整:

import React, { useRef, useEffect, useState } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

function ThreeScene() {
    const mountRef = useRef(null);
    const [scene, setScene] = useState(null);
    const [renderer, setRenderer] = useState(null);
    const [camera, setCamera] = useState(null);
    const [controls, setControls] = useState(null);
    const [pallets, setPallets] = useState([]);

    useEffect(() => {
        const scene = new THREE.Scene();
        setScene(scene);

        const renderer = new THREE.WebGLRenderer();
        setRenderer(renderer);

        const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 5;
        setCamera(camera);

        const controls = new OrbitControls(camera, renderer.domElement);
        setControls(controls);

        const mount = mountRef.current;
        mount.appendChild(renderer.domElement);
        renderer.setSize(mount.clientWidth, mount.clientHeight);

        const animate = function () {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        };

        animate();

        // Handle window resize
        const handleResize = () => {
            const width = mount.clientWidth;
            const height = mount.clientHeight;

            renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        };

        window.addEventListener('resize', handleResize);

        return () => {
            window.removeEventListener('resize', handleResize);
            mount.removeChild(renderer.domElement);
        };
    }, []);

    const createCube = () => {
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
        const cube = new THREE.Mesh(geometry, material);
        cube.position.set(Math.random() * 5 - 2.5, Math.random() * 5 - 2.5, Math.random() * 5 - 2.5);
        scene.add(cube);
        setPallets(pallets => [...pallets, cube]);
    };

    const removeCube = () => {
        if (pallets.length > 0) {
            const lastCube = pallets[pallets.length - 1];
            scene.remove(lastCube);
            setPallets(pallets => pallets.filter(cube => cube !== lastCube));
        }
    };

    return (
        <div>
            <div ref={mountRef} style={{ width: '800px', height: '600px' }} />
            <button onClick={createCube}>Add Cube</button>
            <button onClick={removeCube}>Remove Cube</button>
        </div>
    );
}

export default ThreeScene;

Reactjs相关问答推荐

如何等待我的插入内容提交后再继续执行指令?

父组件更新后不重新呈现子组件

onClick 事件处理程序未应用于样式组件

无法使用 Suspense 和 Await 获取数据

React 为什么标签导致 onClick 事件运行 2 次?

如何测试根据 prop 更改 CSS 属性的 useEffect 钩子?

是的验证:使用 useFieldArray 访问表单值

使用jest如何覆盖对象的模拟?我正在使用`jest.mock()`来模拟对象,并希望 for each 测试用例覆盖模拟.

单击按钮时如何添加或删除 3d 对象

React 测试库包装器组件

条件渲染元素的测试不起作用

如何在对话素材ui中设置边框半径?

React CSSTransition 两次创建新页面并在这两个相同的页面上运行转换

如何在react 中更新子组件中的变量?

从 API 中提取映射数组后出现重复元素

渲染的钩子比预期的少.这可能是由 React Hooks 中意外的提前返回语句引起的

如何定制 React 热 toastr ?

Cypress - 在继续之前等待下一个按钮重新出现

在 redux 状态更改时更新react 按钮禁用状态

在渲染不显示子元素之后,再次渲染时,子元素状态数据完全消失了.为什么会这样以及如何防止它发生?