我试图以动态方式访问引用,但在使用Ref时收到错误"无效的钩子调用.钩子只能在函数组件的主体内调用".这里:
const [subsistemaPlanetario, setSubsistemaPlanetario] = useState([]);
const planetRefs = useRef({});
useEffect(() => {
async function fetchSubsistemaPlanetario() {
try {
const fetchedSubsistemaPlanetario = await getSubsistemaPlanetario();
setSubsistemaPlanetario(fetchedSubsistemaPlanetario);
fetchedSubsistemaPlanetario.forEach((planeta) => {
const camelCaseSlug = planeta.padre.slug.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
planetRefs.current[camelCaseSlug] = useRef(); // <------THIS LINE DROP AN ERROR
});
} catch (error) {
console.error(error);
}
}
fetchSubsistemaPlanetario();
}, []);
整个组件:
import {useFrame} from '@react-three/fiber';
import React, {useRef, useEffect, useState} from 'react';
import {Planet} from './Planet.jsx';
import {Satellite} from './Satellite.jsx';
import {Orbiter} from './utils/Orbiter.js';
import {calculateOrbitalPeriod} from './utils/calculateOrbitalPeriod.js';
import {getSubsistemaPlanetario} from './utils/getSubsistemaPlanetario.js';
export const SubsistemaPlanetario = function SubsistemaPlanetario(props) {
let running = true;
let stopRunning = () => (running = false);
let startRunning = () => (running = true);
const [subsistemaPlanetario, setSubsistemaPlanetario] = useState([]);
const planetRefs = useRef({});
useEffect(() => {
// Obtener el subsistema planetario cuando el componente se monta
async function fetchSubsistemaPlanetario() {
try {
const fetchedSubsistemaPlanetario = await getSubsistemaPlanetario();
setSubsistemaPlanetario(fetchedSubsistemaPlanetario);
fetchedSubsistemaPlanetario.forEach((planeta) => {
const camelCaseSlug = planeta.padre.slug.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
planetRefs.current[camelCaseSlug] = useRef();
console.log(planetRefs);
});
} catch (error) {
console.error(error);
}
}
fetchSubsistemaPlanetario();
}, []);
return (
<>
{subsistemaPlanetario.map((planetaPadre, index) => (
<Planet
key={index}
scale={0.5}
ref={planetRefs.current[index]}
stopRunning={stopRunning}
startRunning={startRunning}
textureType="haumea"
linkTo="areas"
linkToLabel="Areas"
/>
))}
</>
);
};
行星组件
import {forwardRef, useRef, useEffect, useContext, useState} from 'react';
import PropTypes from 'prop-types';
import {useTexture} from '@react-three/drei';
import {useFrame} from '@react-three/fiber';
import barba from '@barba/core';
import {solapaContentAbrir, solapaContentCerrar} from './utils/Solapa.js';
import {planets} from './utils/arrayTexturas.js';
// Define un objeto que mapea los tipos de textura a las rutas de los archivos de textura.
const textureMap = {};
for (const planet of planets) {
textureMap[planet] = `./app/themes/sage/resources/scripts/cosmos/components/textures/${planet}-512.jpg`;
}
export const Planet = forwardRef(function Planet(props, ref) {
// Obtén la ruta de la textura según el tipo especificado en props.textureType.
const texturePath = textureMap[props.textureType] || textureMap.sand;
const texture = useTexture(texturePath);
let rotationX = Math.random();
let rotationY = Math.random();
useFrame((state, delta) => {
ref.current.rotation.x += rotationX * delta;
ref.current.rotation.y += rotationY * delta;
});
return (
<mesh
{...props}
ref={ref}
castShadow
receiveShadow
onPointerEnter={(event) => {
props.stopRunning();
document.body.style.cursor = 'pointer';
solapaContentAbrir('Sección', props.linkToLabel);
event.stopPropagation();
}}
onPointerLeave={(event) => {
props.startRunning();
document.body.style.cursor = 'default';
solapaContentCerrar();
event.stopPropagation();
}}
onClick={(event) => {
barba.go(props.linkTo);
}}
>
<sphereGeometry />
<meshStandardMaterial map={texture} />
</mesh>
);
});
Planet.propTypes = {
stopRunning: PropTypes.func,
startRunning: PropTypes.func,
textureType: PropTypes.oneOf(['haumea', 'mars', 'neptune', 'venus', 'mercury', 'jupiter', 'saturn']),
userData: PropTypes.object,
radius: PropTypes.number,
linkTo: PropTypes.string,
linkToLabel: PropTypes.string,
};
如果有任何帮助,我很感激.