'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 |
|---|
