Reputation: 1015
I am not sure how to frame this question properly but I will try my best to help you understand my problem. I am little bit new to frontend so facing some difficulties. There is a controller called TableViewCotroller
which is written in typescript
and also includes JSX code. This controller is responsible for performing any table related operations. This controller looks like this:
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
/>
);
}
Now I have decided to decouple some of these commands like onInsertRow, onInsertColumn
etc from TableViewController
and move them to TableCommandingController
.
My TableCommandingController
looks like this :
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
}
After creating TableCommandingController
, I have added a variable in TableViewController
called tableCommandingController
. Something like below:
export class TableViewController extends BaseViewController {
private tableCommandingController?: TableCommandingController;
constructor(props: any) {
super(props);
}
//Rest of the class
}
Now I will initialize this tableCommandingController
in async fashion. I don't want to initialize it in synchronous manner(there is some other requirement). So I created a function and I will initialize it in there. Now my TableViewController
looks like this:
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;
}
}
Now when I have tableCommanding
initialized, I wanted to use tableCommanding's
onInsertRow
, onInsertColumn
etc functions inside render
of TableViewController
. But I have no idea how can I do that. I have tried something below but it was not working:
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
/>
);
}
In the above method my tableCommandingController is always uninitialized. So I know that I need to call getCommandingController() to get the initialized value of tableCommandingController. Something like below:
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
/>
);
}
But I cannot make render function async. Any idea how can I do this?
Upvotes: 0
Views: 553
Reputation: 794
Please keep your render
method only to destructure props, state, any small sync operation and returning JSX. Render methods are not meant for async operations. Async operations needs to be handled through react lifecycle methods. Read up lifecycle methods here: https://reactjs.org/docs/state-and-lifecycle.html
You should ideally do this operation in componentDidMount
and use state to re-render your component so that the callbacks are re-assigned. Else, without a re-render, your JSX wouldn't have the actual callback, instead would be undefined as that's what was rendered during mount.
Upvotes: 1