'Converting a class component to function component to use react hooks

Can the following class component be converted into a function component by any chance?

The main issue I'm having is inside the following cellsrenderer function

cellsrenderer: (row, columnfield, value, defaulthtml, columnproperties): string => {
    
           axios
              .get("api/personnels/"+value) 
              .then(response => {
                                  
                this.setState({
                 createdByName: response.data.displayedValues 
                }, ()=> {
                console.log('Inside axios response after setting the state to the name of the project creater')
                 })
            }).catch(err => console.log(err));
                                
            return this.state.createdByName;
    
               }
                  
          }

I am running into an issue of infinite loop because of setState re-rendering issue and want to avoid it by using useEffect() hook maybe if I could but since this is a class component, I am not able to proceed forward.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {FormikApp} from './forms/AddProjectForm'
import JqxGrid, {IGridProps, jqx} from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid';
import JqxButton from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxbuttons'
import {RouteComponentProps} from 'react-router-dom'
import 'jqwidgets-scripts/jqwidgets/styles/jqx.base.css'
import 'jqwidgets-scripts/jqwidgets/styles/jqx.material.css'
import 'jqwidgets-scripts/jqwidgets/styles/jqx.arctic.css'
import {Dialog} from "primereact/dialog";
import {Button} from "primereact/button";
import {properties} from "../properties";
import {Card} from "primereact/card";
import axios from "axios";
import {Messages} from "primereact/messages";
import _ from 'lodash'

export interface IState extends IGridProps {
    projects: [],
    selectedProject: [],
    createdByName :string,
    addDialogVisible: boolean,
    blazerId: string,
    username: string,
    selectedRowIndex: number,
    deleteDialogVisible: boolean
}

class Projects extends React.PureComponent<RouteComponentProps<{}>, IState> {
    private baseUrl = properties.baseUrlWs
    private myGrid = React.createRef<JqxGrid>()
    private messages = React.createRef<Messages>()

    private editrow: number = -1;

    constructor(props: RouteComponentProps) {
        super(props);

        this.selectionInfo = this.selectionInfo.bind(this)
       
        this.gridOnSort = this.gridOnSort.bind(this);

        

      const columns: IGridProps['columns'] = [
            { text: 'Project Name', datafield: 'name', width: 390 },
            { text: 'Project Description', datafield: 'description', width: 390 },
            { text: 'Owner Assigned', datafield: 'institutionId', width: 180,hidden:true },
            { text: 'Created By',  datafield: 'createdBy', 
              
                                  
                cellsrenderer: (row, columnfield, value, defaulthtml, columnproperties): string => {

                            axios
                            .get("api/personnels/"+value) 
                            .then(response => {
                              
                                    this.setState({
                                        createdByName: response.data.displayedValues 
                                    }, ()=> {
                                        console.log('Inside axios response after setting the state to the name of the project creater')
                                    })
                                }).catch(err => console.log(err));
                            
                
                return this.state.createdByName;

                }
               
            }
           
            ]

        const source:any = {
            dataFields: [
                { name: 'id', type: 'long'},
                { name: 'name', type: 'string' },
                { name: 'description', type: 'string' },
                { name: 'url', type: 'string'},
                { name: 'irbProtocol', type: 'string'},
                { name: 'institutionId', type: 'long' },
                { name: 'projectType', type: 'string' },
                { name: 'priority', type: 'string'},
                { name: 'researchDataSetType', type: 'string'},
                { name: 'statusIndicatorId', type: 'long'},
                { name: 'createdBy', type: 'string' }
            ],
            dataType: 'json',
            root: 'projects',
            sortColumn: 'name',
            sortdirection: 'asc',
            url: this.baseUrl + 'api/projects/search/getProjectsById',
            data: {
                value: ''
            }
        }

        const dataAdapter:any = new jqx.dataAdapter(source,
            {
                autoBind: true,
                downloadComplete: (data:any, status:any, xhr:any):void => {
                    // if (!source.totalrecords) {
                        source.totalrecords = parseInt(data['page'].totalElements);
                    // }
                },
                formatData: (data:any):any => {
                  
                    data.page = data.pagenum
                    data.size = data.pagesize
                    if (data.sortdatafield && data.sortorder) {
                        data.sort = data.sortdatafield + ',' + data.sortorder;
                    }
                    return data;
                },
                loadError (xhr, status, error) {
                    throw new Error('Error occurred in getting Projects for user ' + error.toString());
                }
            }
        );

        

        this.state = {
            projects: [],
            selectedProject: [],
            createdByName : '',
            blazerId: '',
            username: '',
            addDialogVisible: false,
            selectedRowIndex: null,
            deleteDialogVisible: false,
            columns: columns,
            rendergridrows: (params: any): any[] => {
                const data = params.data
                return data;
            },
            source: dataAdapter,
           
        };
    }

    setValueProperty = (data:any):any => {
        if (this.state && this.state.blazerId) {
            data.value = this.state.blazerId
        }
    }

   

    private gridOnSort(event: any): void {
        const sortinformation = event.args.sortinformation;
        let sortdirection = sortinformation.sortdirection.ascending ? 'ascending' : 'descending';
        if (!sortinformation.sortdirection.ascending && !sortinformation.sortdirection.descending) {
            sortdirection = 'null';
        }
        this.myGrid.current.updatebounddata('sort')
    };

    selectionInfo = (event: any): void => {
        const selection = this.myGrid.current.getrowdata(event.args.rowindex)

       this.setState({
            selectedProject: selection
        }, () => {
            console.log('pushing ' + this.state.selectedProject)
            this.props.history.push({
                pathname: '/project',
                state: {
                    project: this.state.selectedProject,
                    blazerId: this.state.blazerId
                }
            })
        });
    }

   

   

   
    componentDidMount() {
        console.log('In Projects.componentDidMount....' + sessionStorage.getItem('loggedInUser'))
        if (sessionStorage.getItem('loggedInUser') != null) {
            const loggedInUser = JSON.parse(sessionStorage.getItem('loggedInUser') as string)
            this.setState({ employeeId: loggedInUser.employeeId})
        }
    }

    render() {
        

        const defaultView = this.state.addDialogVisible ? null : (this.state.employeeId && !_.isEmpty(this.state.employeeId)) ? (
            <div style={{width: '100%', margin: '0 auto', display: 'table'}}>
                <JqxGrid
                    // @ts-ignore
                    ref={this.myGrid}
                    theme={'arctic'}
                    altrows={true}
                    width="100%"
                    autoheight={true}
                    source={this.state.source}
                    columns={this.state.columns}
                    pageable={true}
                    sortable={true}
                    onSort={this.gridOnSort}
                    pagesize={20}
                    virtualmode={true}
                    rendergridrows={this.state.rendergridrows}
                    showtoolbar={true}
                    rendertoolbar={this.state.rendertoolbar}
                    columnsresize={true}/>
            </div>
        ) : null

       

        return (
            <div className="project-page-main">
            <Messages ref={this.messages} style={{width: '100%', margin: 'auto' }}/>
            <div className="content">
               
                {defaultView}
              
            </div>
            </div>
        );
    }
}
export default Projects;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source