繁体   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