首页 > 解决方案 > 如何将函数传递给 React 的渲染函数

问题描述

我不确定如何正确地提出这个问题,但我会尽力帮助您理解我的问题。我对前端有点陌生,所以面临一些困难。有一个名为的控制器TableViewCotroller,它是用编写的typescript ,还包含 JSX 代码。该控制器负责执行任何与表相关的操作。这个控制器看起来像这样:

import * as React from 'react';

export class TableViewController extends BaseViewController {
  constructor(props: any) {
    super(props);
  }
protected onInsertRow = async (arg: InsertArgument) => {
    //some row insertion logic
  };

protected onDeleteRow = async (arg: InsertArgument) => {
    //some row deletion logic
  };

protected onInsertColumn = async (arg: InsertArgument) => {
    //some column insertion logic
  };

protected onDeleteColumn = async (arg: InsertArgument) => {
    //some Column deletion logic
  };

render()
{
 const {//some properties} = this.props
 const {//state1, state2 etc} = this.state
 return (
  <Table
  onInsertRow={this.onInsertRow}
  onDeleteRow={this.onDeleteRow}
  onInsertColumn={this.onInsertColumn}
  onDeleteColumn={this.onDeleteColumn}
  ...//some other properties like this
 />
 );
}

现在我决定将其中一些命令(如onInsertRow, onInsertColumnetc)TableViewControllerTableCommandingController. 我的TableCommandingController样子是这样的:

export class TableCommanding implements ITableCommandingController{
constructor(props: any) {
    super(props);
  }
    protected onDeleteRow = async (arg: InsertArgument) => {
        //some row deletion logic
      };
    
    protected onInsertColumn = async (arg: InsertArgument) => {
        //some column insertion logic
      };
    
    protected onDeleteColumn = async (arg: InsertArgument) => {
        //some Column deletion logic
      };
    
   //Some other commands
}

创建后TableCommandingController,我在TableViewController调用中添加了一个变量tableCommandingController。如下所示:

export class TableViewController extends BaseViewController {

private tableCommandingController?: TableCommandingController;
  constructor(props: any) {
    super(props);
  }

//Rest of the class
}

现在我将以tableCommandingController异步方式初始化它。我不想以同步方式初始化它(还有一些其他要求)。所以我创建了一个函数,我将在那里初始化它。现在我的TableViewController样子是这样的:

export class TableViewController extends BaseViewController {

    private tableCommandingController?: TableCommandingController;

    constructor(props: any) {
        super(props);
    }

    protected getCommandingController = async () => {
        if (this.tableCommandingController !== undefined) return this.tableCommandingController;

        //Here I will lazy load TableCommandingModule using webpack magic comment
       const {TableCommanding } = await import(/* webpackChunkName: "TableCommandingController" */ './TableCommandingController');
       this.tableCommandingController = new TableCommanding(this.props);
       return this.tableCommandingController;
    }
}

现在,当我初始化后,tableCommanding我想在. 但我不知道我该怎么做。我在下面尝试了一些方法,但它不起作用:tableCommanding's onInsertRowonInsertColumnrenderTableViewController

render()
    {
     const {//some properties} = this.props
     const {//state1, state2 etc} = this.state
     return (
      <Table
      onInsertRow={this.tableCommandingController?.onInsertRow}
      onDeleteRow={this.tableCommandingController?.onDeleteRow}
      onInsertColumn={this.tableCommandingController?.onInsertColumn}
      onDeleteColumn={this.tableCommandingController?.onDeleteColumn}
      ...//some other properties like this
     />
     );
    }

在上述方法中,我的 tableCommandingController 始终未初始化。所以我知道我需要调用getCommandingController()来获取tableCommandingController的初始化值。如下所示:

async render()
    {
     const commanding = await this.getTableCommandingController();
     const {//some properties} = this.props
     const {//state1, state2 etc} = this.state
     return (
      <Table
      onInsertRow={commanding .onInsertRow}
      onDeleteRow={commanding .onDeleteRow}
      onInsertColumn={commanding .onInsertColumn}
      onDeleteColumn={commanding .onDeleteColumn}
      ...//some other properties like this
     />
     );
    }

但我不能使渲染功能异步。知道我该怎么做吗?

标签: reactjstypescript

解决方案


请保留您的render方法仅用于解构道具、状态、任何小的同步操作和返回 JSX。渲染方法不适用于异步操作。异步操作需要通过 react 生命周期方法来处理。在此处阅读生命周期方法:https ://reactjs.org/docs/state-and-lifecycle.html

理想情况下,您应该执行此操作componentDidMount并使用 state 重新渲染您的组件,以便重新分配回调。否则,如果没有重新渲染,您的 JSX 将没有实际的回调,而是未定义,因为这是在挂载期间渲染的内容。


推荐阅读