为了账号安全,请及时绑定邮箱和手机立即绑定

如何从父组件调用子组件方法

如何从父组件调用子组件方法

慕的地10843 2021-11-04 17:44:51
在我的 Reactjs 应用程序中,我需要有一个名为Wizard.js的父组件(一个向导)和一些名为PrimaryForm.js、 SecondaryForm.js 等的子组件(向导的步骤)。它们都是基于类的组件,有一些本地验证功能。用于推进步骤的“上一步”和“下一步”按钮位于 Wizard.js 中。为了推进向导的下一步,我试图从 PrimaryForm 调用一个方法。我在 Stackoverflow 中检查了类似的问题;尝试使用 ref 或 forwardRef,但我无法使其工作。我目前收到“类型错误:无法读取 null 的属性‘handleCheckServer’ ”错误。下面是我的父子类。任何有关我将做错的事情的帮助表示赞赏。向导.js:import React, { Component } from 'react';...const getSteps = () => {  return [    'Info',    'Source Details',    'Target Details',    'Configuration'  ];}class Wizard extends Component {  constructor(props) {    super(props);    this.firstRef = React.createRef();    this.handleNext = this.handleNext.bind(this);    this.state = {      activeStep: 1,    }}  componentDidMount() {}  handleNext = () =>  {    if (this.state.activeStep === 1) {      this.firstRef.current.handleCheckServer(); <<<<<<<<<<<<<<<<< This is where I try to call child method    }    this.setState(state => ({      activeStep: state.activeStep + 1,    }));  };  handleBack = () => {    this.setState(state => ({      activeStep: state.activeStep - 1,    }));  };  handleReset = () => {    this.setState({      activeStep: 0,    });  };  render() {    const steps = getSteps();    const currentPath = this.props.location.pathname;    const { classes } = this.props;    return (      <React.Fragment>        <CssBaseline />        <Topbar currentPath={currentPath} />        <div className={classes.root}>          <Grid container spacing={2} justify="center" direction="row">            <Grid container spacing={2} className={classes.grid} justify="center" direction="row">              <Grid item xs={12}>                <div className={classes.topBar}>                  <div className={classes.block}>                    <Typography variant="h6" gutterBottom>Wizard</Typography>                    <Typography variant="body1">Follow the wizard steps to create a configuration.</Typography>                  </div>                </div>              </Grid>
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

打字稿中的示例。这个想法是父级将其回调传递给子级。孩子调用父母的回调,提供自己的例如子回调作为参数。父级将它得到的(子回调)存储在一个类成员变量中并稍后调用它。


import * as React from 'react'


interface ICallback {

  (num: number): string

}


type ChildProps = {

  parent_callback: (f: ICallback) => void;

}


class Child extends React.Component {

  constructor(props: ChildProps) {

    super(props);

    props.parent_callback(this.childCallback);

  }


  childCallback: ICallback = (num: number) => {

    if (num == 5) return "hello";

    return "bye";

  }


  render() {

    return (

      <>

        <div>Child</div>

      </>

    )

  }

}


class Parent extends React.Component {

  readonly state = { msg: "<not yet set>" };


  letChildRegisterItsCallback = (fun: ICallback) => {

    this.m_ChildCallback = fun;

  }


  callChildCallback() {

    const str = this.m_ChildCallback? this.m_ChildCallback(5) : "<callback not set>";

    console.log("Child callback returned string: " + str);

    return str;

  }


  componentDidMount() {

    this.setState((prevState) => { return {...prevState, msg: this.callChildCallback()} });

  }


  render() {

    return (

      <>

        <Child {...{ parent_callback: this.letChildRegisterItsCallback }} />

        <div>{this.state.msg}</div>

      </>

    )

  }


  m_ChildCallback: ICallback | undefined = undefined;

}

PS

Javascript 中的相同代码。唯一的区别是interface, type, readonly去掉了和类型注解。粘贴到此处确认它是有效的 ES2015 stage-2 代码。


class Child extends React.Component {

  constructor(props) {

    super(props);

    props.parent_callback(this.childCallback);

  }


  childCallback = (num) => {

    if (num == 5) return "hello";

    return "bye";

  }


  render() {

    return (

      <>

        <div>Child</div>

      </>

    )

  }

}


class Parent extends React.Component {

  state = { msg: "<not yet set>" };


  letChildRegisterItsCallback = (fun) => {

    this.m_ChildCallback = fun;

  }


  callChildCallback() {

    const str = this.m_ChildCallback? this.m_ChildCallback(5) : "<callback not set>";

    console.log("Child callback returned string: " + str);

    return str;

  }


  componentDidMount() {

    this.setState((prevState) => { return {...prevState, msg: this.callChildCallback()} });

  }


  render() {

    return (

      <>

        <Child {...{ parent_callback: this.letChildRegisterItsCallback }} />

        <div>{this.state.msg}</div>

      </>

    )

  }


  m_ChildCallback = undefined;

}


查看完整回答
反对 回复 2021-11-04
  • 1 回答
  • 0 关注
  • 170 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信