【发布时间】:2023-03-08 05:58:01
【问题描述】:
我有一个表格组件,其中许多表格列的处理方式类似。 有没有办法优化这段代码,也许在一个单独的函数中?
import useTableStyles from 'admin/components/table/AdminTable.styles';
import useStyles from 'portal/pages/wasOperators/views/ViewEditOperators.style';
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { toast } from 'react-toastify';
import { Form } from 'shared/components/Form';
import WssoService from 'shared/services/WssoService';
import DateFnsUtils from '@date-io/date-fns';
import { Button, Grid, TextField } from '@material-ui/core';
import { DatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
interface Props {
isEditing?: boolean;
}
const BenchmarkingTable: React.FC<Props> = ({ isEditing }) => {
const tableClasses = useTableStyles();
const classes = useStyles();
const { t } = useTranslation();
const { operatorsId }: any = useParams();
const valuesForInverseCalculation = [
'continuityWaterSupply',
'totalLossesWaterSupplySystems',
'pressureWaterSupplySystem',
'sewerNetworkAccidents',
'floodsThirdPartyCausedBySewage',
];
const benchmarkingDetailsInit = {
levelWaterSupplyServices: {
target: '',
result: '',
status: '',
},
qualityDrinkWaterLargeAreas: {
target: '',
result: '',
status: '',
},
qualityDrinkWaterSmallAreas: {
target: '',
result: '',
status: '',
},
monitorQualityDrinkWater: {
target: '',
result: '',
status: '',
},
continuityWaterSupply: {
target: '',
result: '',
status: '',
},
totalLossesWaterSupplySystems: {
target: '',
result: '',
status: '',
},
pressureWaterSupplySystem: {
target: '',
result: '',
status: '',
},
levelCoverageServiceDisposalOfWastewater: {
target: '',
result: '',
status: '',
},
levelCoverageServiceTreatmentOfWastewater: {
target: '',
result: '',
status: '',
},
wastewaterQuality: {
target: '',
result: '',
status: '',
},
sewerNetworkAccidents: {
target: '',
result: '',
status: '',
},
floodsThirdPartyCausedBySewage: {
target: '',
result: '',
status: '',
},
};
const [data, setData] = useState<any>(benchmarkingDetailsInit);
const [KEY, setKEY] = useState<any>(new Date());
useEffect(() => {
(async () => {
const result: any = await WssoService.getBenchmarking(
operatorsId,
KEY.getFullYear()
);
if (result && result.data && result.data.json) {
setData(JSON.parse(result.data.json));
} else {
setData(null);
}
})();
/* eslint-disable react-hooks/exhaustive-deps */
}, [KEY, operatorsId]);
const HandleKEYChange = () => {
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker
variant="inline"
inputVariant="outlined"
format={'yyyy'}
views={['year']}
onChange={setKEY}
value={KEY}
/>
</MuiPickersUtilsProvider>
);
};
const updateBenchmarking = async (editValues: any) => {
const request = {
json: JSON.stringify(editValues),
};
const result: any = await WssoService.editAddBenchmarking(
operatorsId,
KEY.getFullYear(),
request
);
if (result && result.data && result.json) {
setData(JSON.parse(result.data.json));
}
};
const onUpdateSuccess = () => {
toast.success(t('itemUpdateSuccessfully'));
};
const handleSaveData = async () => {
if (data) {
await updateBenchmarking(data);
onUpdateSuccess();
}
};
const handleOnTextChange = (
key: string,
valueKey: string,
e: React.ChangeEvent<HTMLInputElement>
) => {
const value = e.target.value;
const newData = Object.assign({}, data, {
[key]: Object.assign({}, data[key], {
[valueKey]: value,
}),
});
setData(newData);
};
const handleColorChange = (name: any, target: any, result: any) => {
const removePercentFromTarget = target.includes('%')
? target.slice(0, -1)
: target;
const convertedTarget = Number(removePercentFromTarget);
const removePercentFromResult = result.includes('%')
? result.slice(0, -1)
: result;
const convertedResult = Number(removePercentFromResult);
target = convertedTarget;
result = convertedResult;
let final: any;
const arrOfNames = [];
arrOfNames.push(name);
if (arrOfNames.some(x => valuesForInverseCalculation.includes(x))) {
if (target < result) {
Object.keys(data).map(k => {
return (final = data[k].status = 'red');
});
} else if (target > result) {
Object.keys(data).map(k => {
return (final = data[k].status = 'green');
});
} else if (target === result) {
Object.keys(data).map(k => {
return (final = data[k].status = 'yellow');
});
}
} else {
if (target > result) {
Object.keys(data).map(k => {
return (final = data[k].status = 'red');
});
} else if (target < result || (target === result && result === 100)) {
Object.keys(data).map(k => {
return (final = data[k].status = 'green');
});
} else if (target === result) {
Object.keys(data).map(k => {
return (final = data[k].status = 'yellow');
});
}
}
return final;
};
const updateData = (newData: any[]) => {
setData(newData);
};
const renderBenchmarkDetails = () => {
if (isEditing) {
return data ? (
Object.keys(data).map(k => {
return (
<tr>
<td>{t(k)}</td>
<td className={classes.benchTextfieldAlign}>
<TextField
type="text"
onChange={(e: any) => handleOnTextChange(k, 'target', e)}
value={data[k].target}
inputProps={{ min: 0, style: { textAlign: 'center' } }}
required
/>
</td>
<td className={classes.benchTextfieldAlign}>
<TextField
type="text"
onChange={(e: any) => handleOnTextChange(k, 'result', e)}
value={data[k].result}
inputProps={{ min: 0, style: { textAlign: 'center' } }}
required
/>
</td>
</tr>
);
})
) : (
<tr>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
</tr>
);
} else {
return data ? (
Object.keys(data).map((rowName, i) => {
return (
<tr key={i}>
<td>{t(rowName)}</td>
<td className={classes.benchTextfieldAlign}>
{data[rowName].target}
</td>
<td className={classes.benchTextfieldAlign}>
{data[rowName].result}
</td>
<td className={classes.benchTextfieldAlign}>
<div
style={{
width: '15px',
height: '15px',
borderRadius: '50%',
backgroundColor: handleColorChange(
rowName,
data[rowName].target,
data[rowName].result
),
}}
/>
</td>
</tr>
);
})
) : (
<tr>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
<td>{t('noDetailsToDisplay')}</td>
</tr>
);
}
};
const handleExport = useCallback(async () => {
const dataRows: any = [];
if (data) {
Object.keys(data).map(rowName => {
dataRows.push([t(rowName), data[rowName].target, data[rowName].result]);
return null;
});
}
let dataToCSV: any[][] = [];
if (dataRows && dataRows.length > 0) {
dataToCSV = [[t('criteria'), t('targets'), t('results')], ...dataRows];
const csvContent: string =
'data:text/csv;charset=utf-8,\uFEFF' +
dataToCSV
.map(e =>
e
.map(r =>
r instanceof Array
? `"${(r ?? '').toString().replace(',', ', ')}"`
: (r ?? '').toString().replace(',', ' ')
)
.join(',')
)
.join('\n');
const encodedUri: string = encodeURI(csvContent);
const link: HTMLAnchorElement = document.createElement('a');
link.setAttribute('href', encodedUri);
link.setAttribute('download', `${t('exportedTableData')}.csv`);
link.click();
}
}, [data, t]);
console.log(operatorsId);
console.log(benchmarkingDetailsInit);
console.log(updateBenchmarking);
return (
<Grid>
<Form
onSubmit={(formData, { resetForm }) => {
const tempData = !!operatorsId
? {
...formData,
}
: {
...formData,
...(!!operatorsId && {
operatorsAreaEntity: {
id: parseInt(operatorsId, 0),
},
}),
id: operatorsId ? undefined : Date.now(),
};
updateData([tempData, ...data]);
resetForm();
}}
initialValues={benchmarkingDetailsInit}
enableReinitialize={true}
>
<div className={classes.tableContainer}>
<Grid item xs={12}>
<div className={classes.containerLegendBench}>
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
}}
>
<div className={classes.yearBoxBenchmarketType}>
<HandleKEYChange />
</div>
<div className={classes.legendBoxBenchmarketType}>
{t('reachedResult')}
<div
style={{
marginLeft: '3px',
width: '11px',
height: '9px',
borderRadius: '50%',
backgroundColor: '#006400',
display: 'inline-block',
}}
/>
</div>
<div className={classes.legendBoxBenchmarketType}>
{t('almostReachedResult')}
<div
style={{
marginLeft: '3px',
width: '11px',
height: '9px',
borderRadius: '50%',
backgroundColor: '#FFDF00',
display: 'inline-block',
}}
/>
</div>
<div className={classes.legendBoxBenchmarketType}>
{t('notReachedResult')}
<tr
style={{
marginLeft: '3px',
width: '11px',
height: '9px',
borderRadius: '50%',
backgroundColor: '#FF0000',
display: 'inline-block',
}}
/>
</div>
</div>
</div>
</Grid>
<table className={tableClasses.table}>
<thead>
<tr>
<th>{t('criteria')}</th>
<th>{t('targets')}</th>
<th>{t('results')}</th>
<th />
</tr>
</thead>
<tbody>{renderBenchmarkDetails()}</tbody>
</table>
</div>
<Grid item xs={12}>
<Button
style={{ margin: '5px 0px 10px 10px' }}
type="button"
color="primary"
variant="contained"
onClick={handleExport}
disabled={!data}
>
{t('export')}
</Button>
</Grid>
{isEditing && (
<Button onClick={handleSaveData} className={classes.submitButton}>
{t('save')} <i className={`fas fa-save ${classes.submitIcon}`} />
</Button>
)}
</Form>
</Grid>
);
};
export default BenchmarkingTable;
【问题讨论】:
-
你指的是什么代码?我只能看到两个图像。请您将代码作为文本添加到问题中作为minimal reproducible example?
-
至少提供图片的文字版
-
仅来自该文件的整个代码 - 来自代码框,抱歉,我是新来的 :)
-
欢迎来到 Stack Overflow!以下是如何获得更多帮助。 1. 编辑您的问题并将相关代码粘贴为代码块中的文本。然后,我们可以在创建您的答案时复制并粘贴该代码。 2. 多描述一下你的问题。目前还不清楚“用单独的函数重构是什么意思”。
标签: javascript reactjs typescript