簡體   English   中英

React.js:從其父類調用子組件函數/方法

[英]React.js: Call a child component function/method from its parent class

如何從包含子類的組件中調用子類的函數?

這是我的子類代碼:

import React, { useRef, useEffect } from 'react'
import { useGLTF, useAnimations } from '@react-three/drei'

export default function Model({ ...props }) {
  function changeAnimation(animationName) {
    //const animationFileNames = ["Idle", "Ready", "NinjaIdle", "HappyIdle"]
    //get GLB file name
    const glbFileName = '/'+animationName+'.glb'
    //set const animation 
    const { animations } = useGLTF(glbFileName)
    //get action from the animations
    const { actions } = useAnimations(animations, group)
    useEffect(()=> {
        console.log(actions)
        //actions['idle'].play();
    })
  }
  const group = useRef()
  const { nodes, materials } = useGLTF('/ninjaIdle.glb')
  const { animations } = useGLTF('/idle.glb')
  const { actions } = useAnimations(animations, group)
  useEffect(() => {
    console.log(actions['idle']);
    actions['idle'].play();
  });
  return (
    <group ref={group} {...props} dispose={null}>
      <group name="Scene" position={[0,-0.93,0]}>
        <group name="Armature" >
          <primitive object={nodes.Hips} />
          <skinnedMesh name="Wolf3D_Body" geometry={nodes.Wolf3D_Body.geometry} material={materials.Wolf3D_Body} skeleton={nodes.Wolf3D_Body.skeleton} />
          <skinnedMesh name="Wolf3D_Hair" geometry={nodes.Wolf3D_Hair.geometry} material={materials.Wolf3D_Hair} skeleton={nodes.Wolf3D_Hair.skeleton} />
          <skinnedMesh name="Wolf3D_Outfit_Bottom" geometry={nodes.Wolf3D_Outfit_Bottom.geometry} material={materials.Wolf3D_Outfit_Bottom} skeleton={nodes.Wolf3D_Outfit_Bottom.skeleton} />
          <skinnedMesh name="Wolf3D_Outfit_Footwear" geometry={nodes.Wolf3D_Outfit_Footwear.geometry} material={materials.Wolf3D_Outfit_Footwear} skeleton={nodes.Wolf3D_Outfit_Footwear.skeleton} />
          <skinnedMesh name="Wolf3D_Outfit_Top" geometry={nodes.Wolf3D_Outfit_Top.geometry} material={materials.Wolf3D_Outfit_Top} skeleton={nodes.Wolf3D_Outfit_Top.skeleton} />
          <skinnedMesh name="EyeLeft" geometry={nodes.EyeLeft.geometry} material={materials.Wolf3D_Eye} skeleton={nodes.EyeLeft.skeleton} morphTargetDictionary={nodes.EyeLeft.morphTargetDictionary} morphTargetInfluences={nodes.EyeLeft.morphTargetInfluences} />
          <skinnedMesh name="EyeRight" geometry={nodes.EyeRight.geometry} material={materials.Wolf3D_Eye} skeleton={nodes.EyeRight.skeleton} morphTargetDictionary={nodes.EyeRight.morphTargetDictionary} morphTargetInfluences={nodes.EyeRight.morphTargetInfluences} />
          <skinnedMesh name="Wolf3D_Head" geometry={nodes.Wolf3D_Head.geometry} material={materials.Wolf3D_Skin} skeleton={nodes.Wolf3D_Head.skeleton} morphTargetDictionary={nodes.Wolf3D_Head.morphTargetDictionary} morphTargetInfluences={nodes.Wolf3D_Head.morphTargetInfluences} />
          <skinnedMesh name="Wolf3D_Teeth" geometry={nodes.Wolf3D_Teeth.geometry} material={materials.Wolf3D_Teeth} skeleton={nodes.Wolf3D_Teeth.skeleton} morphTargetDictionary={nodes.Wolf3D_Teeth.morphTargetDictionary} morphTargetInfluences={nodes.Wolf3D_Teeth.morphTargetInfluences} />
        </group>
      </group>
    </group>
  )
}

這是父類:

import React, { Component, Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, View } from "@react-three/drei";
import { Container } from "react-bootstrap";
import $ from 'jquery'

import Radio from "./Radio"
import Ninja from "./NinjaIdle"; //<-- This is the child class file

import "./styles.css";
import 'bootstrap/dist/css/bootstrap.min.css';
import { render } from "react-dom";

export default class App extends Component {
    /** some function here to call the child component function "changeAnimation"*/
  render(){
    return (
      <div className="row h-100" style={{}}>
        <div className="col-2 btn-group-vertical" id="buttonContainer">
          <Radio/>
        </div>
        <div id="modelContainer" className="h-100 col-8 d-inline-block">
          <Canvas  camera={{position: [-3, 6, 20], fov: 5.3}}>
            <OrbitControls />
            <ambientLight intensity={0.6} />
            <directionalLight intensity={0.5} />
            <Suspense fallback={null}>
              <Ninja/>
            </Suspense>
          </Canvas>
        </div>
      </div>
    )
  }
}

我知道還有很多其他帖子可以回答這個問題。 就我而言,我想:

1.在子類中聲明函數(包含的子類屬性太多)

2.從父類調用它(如果可能的話傳遞參數?)

這可能嗎? 如果是,您會推薦什么實施方法? 先感謝您。

我認為這就是您正在尋找的內容https://reactjs.org/docs/forwarding-refs.html

const ChildComponent = React.forwardRef((props, ref) => {

    const functionName = () => {
      // do something
    }

    useImperativeHandle(ref, () => ({ functionName }), [functionName]);

    return (
        <div>
            // your component 
        </div>
})

const ParentComponent = props => {
    const myRef = React.useRef()

    const yourCustomFuction = () => {
      if (myRef.current) {
        myRef.current.functionName();
      }
    }
    
    return (
        <ChildComponent
            ref={myRef}
            ...
        />
    )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM