React:无法在子组件内调用函数

IT技术 function reactjs call
2021-05-27 13:26:43

我试图通过 this.refs 在子组件中调用一个函数,但我不断收到这个函数不存在的错误。

Uncaught TypeError: this.refs.todayKpi.loadTodaysKpi is not a function

父组件:

class KpisHeader extends React.Component {

  constructor() {
    super();
    this.onUpdate = this.onUpdate.bind(this);
  }
    render(){
        return <div>
            <DateRange ref="dateRange" onUpdate={this.onUpdate}/>
            <TodayKpi ref="todayKpi" {...this.state}/>
          </div>;
    }

  onUpdate(val){

      this.setState({
          startDate: val.startDate,
          endDate: val.endDate
      }, function(){
        this.refs.todayKpi.loadTodaysKpi();
      });
  } 
 }

我想通过函数 onUpdate 从 DateRange 组件获取一些数据,然后我想触发 TodayKpi 中的一个函数,该函数从服务器获取数据。现在它只是 console.log("AAA");。

子组件:

class TodayKpi extends React.Component {
    constructor() {
        super();
        this.loadTodaysKpi = this.loadTodaysKpi.bind(this);
    }

    render(){
        console.log(this.props.startDate + " "+ this.props.endDate);
        return <div className="today-kpi">


          </div>;
    }
    loadTodaysKpi(){
        console.log("AAAA");
    }
}

我应该如何实施?

2个回答

由于我还不明白的原因,React 不鼓励从父级调用子方法。然而,他们松了口气,给了我们一个“逃生舱”,允许这样做。您认为“参考”是逃生舱口的一部分是正确的。如果像我一样,您已经阅读了数十篇搜索此信息的文章,那么您将准备好理解他们对逃生舱口的描述

在你的情况下,你可能想在你的 KpisHeader 类中尝试这样的事情。

改变这一行

<TodayKpi ref="todayKpi" {...this.state}/>

使用类似这样的 ref 回调函数:

<TodayKpi ref={(todayKpiComponent) => this.todayKpiComponent = todayKpiComponent} {...this.state}/>

或者,在 ES6 之前,这个:

<TodayKpi 
    ref= 
    {
        function (todayKpiComponent)
        {
            this.todayKpiComponent = todayKpiComponent      
        }
    }
    {...this.state}
 />

然后您将能够从您的 KpisHeader 类访问您的 todayKpi 组件方法,如下所示:

this.todayKpiComponent.someMethod();

奇怪的是,对我来说,在 ref 回调函数中,'this' 是窗口而不是父组件。所以,我不得不补充

var self = this;

在 render 方法上方并在 ref 回调函数中使用“self”。

就我而言,我有未知数量的动态生成的子组件,因此我将每个组件都放入一个数组中。我清除了 componentWillUpdate 中的数组。这一切似乎都在起作用,但我有一种不安的感觉,尤其是考虑到 React 对调用儿童方法的厌恶。

如果您希望在子级内部调用函数/方法,则应首先将其从父级传递给子级。你需要改变的另一件事是onUpdateonChange,假设你要跟踪每一个变化到该领域。另一种选择是检查何时发生onSubmit,但听起来您希望每次更新字段时都发生。