I'm using react three fiber and i have two components one to make a box and the other is to make an array of this box
here's how they look like, the platform component:
export function Plat() {
const [active, setActive] = useState(0)
const { scale } = useSpring({ scale: active ? 1 : 0.4 })
const [mat] = useState(() => new THREE.TextureLoader().load('/matcap.png'))
function Shape(props) {
return (
<animated.mesh {...props} scale={scale} onPointerOver={() => setActive(Number(!active))} >
<RoundedBox args={[60,20,60]} radius={4} smoothness={4} position={[0, -10, 0]} dispose={null} >
<meshMatcapMaterial matcap={mat} />
</RoundedBox>
</animated.mesh>
);
}
useEffect(() => {
(function() {
setActive((1))
})();
},[]);
return (
<Shape />
)
}
and the component that makes an array of this platform:
import {Plat} from './Plat'
export default function Boxes() {
function MyShape(props) {
return (
<mesh {...props} >
<Plat />
</mesh>
);
}
const [shapes, setShapes] = useState([<MyShape key={0} position={[100, 100, 100]} />, <MyShape key={1} position={[120, 120, 120]} />, <MyShape key={2} position={[130, 130, 130]} />]);
return (
<group >
{[...shapes]}
</group>
)
}
(I have more than 3 elements in the array) I wanna know if there's a way to access the variables inside each of the array's platform components how would I do something like this:
console.log(shapes[2].position) or change the position of this specific shape in the array or this shapes[1].setActive(1)
is it even possible?
CodePudding user response:
Few pointer
- Avoid nesting functional components
Plat Shape // declare this outside and pass it the params from parent
If you need to change the position of the children, consider creating a array with the information you need to change
const [shapes, setShapes] = useState<>([{ key: 1, position: { x: 5, y: 10 } }]) const changeShapePostions = (key) => { setShapes(items => { return items.map(shape => { if (shape.id === key) { return { ...shape, position: { x: updatedX, y: updated: y} } } else { return shape } } } } const setActive = (key) => { setShapes(items => { return items.map(shape => { if (shape.id === key) { return { ...shape, isActive: true } } else { return shape } } } } return ( <group > { shapes.map(shape => { return (<MyShape key={shape.key} position={shape.position} setActive={setActive} />) } } </group> )
you can check standard practices on working with arrays
Hope it helps in some ways