reactjs - Material-ui 可编辑表格单元格,带有货币掩码和表格页脚用于总计
问题描述
我有一个Material-ui
必须可编辑的表,每个字段都必须有一个货币掩码,并且该表有一个页脚,用于对每列的行值求和。
我想在输入单元格时更新表格页脚总数。
问题是:要在输入单元格时更新表格页脚总数,我必须执行setState
强制重新渲染组件的操作,并且我在该字段中失去焦点并且无法再编辑。
const InputCurrency = ({ value, onChange }) => {
return (
<CurrencyTextField
currencySymbol="€"
decimalCharacter=","
digitGroupSeparator=" "
value={value}
onChange={onChange}
/>
);
};
const tableTotalSum = tableData => {
return tableData.reduce((sum, row) => sum + (row.total ? row.total : 0), 0);
};
const tableTaxSum = tableData => {
return tableData.reduce((sum, row) => sum + (row.tax ? row.tax : 0), 0);
};
function currencyFormat(num) {
return `${num.toFixed(2)}`;
}
export default function App() {
const tableData = [
{
total: 100,
tax: 1
},
{
total: 200,
tax: 4
},
{
total: 300,
tax: 33
},
{
total: 400,
tax: 40
}
];
const [state, setState] = React.useState(tableData);
const removeRowHandler = index => () => {
setState(prevState => {
const newTableData = [...prevState];
newTableData.splice(index, 1);
return newTableData;
});
};
const addRow = () => {
setState(prevState => {
const newTableData = [...prevState];
newTableData.push({});
//onChangeTableData(newTableData);
return newTableData;
});
};
const changeValueHandler = (index, value, prop) => {
setState(prevState => {
prevState[index][prop] = value;
return prevState;
/**
* TODO this is the problem - If I return [...prevState], this causes
* a re-render and I loose focus and can't edit.
* If I just return prevState, it does not cause a re-render,
* but the total is not updated
*/
//return [...prevState];
});
};
const TableEditRow = ({ row, index, changeValueHandler }) => {
const [total, setTotal] = React.useState(row.total ? row.total : "");
const [tax, setTax] = React.useState(row.tax ? row.tax : "");
const onChange = (setter, prop) => (event, value) => {
setter(value);
changeValueHandler(index, value, prop);
};
return (
<TableRow>
<TableCell align="right">
<InputCurrency value={total} onChange={onChange(setTotal, "total")} />
</TableCell>
<TableCell align="right">
<InputCurrency value={tax} onChange={onChange(setTax, "tax")} />
</TableCell>
<TableCell align="right" className="MuiTableCell-paddingNone">
<IconButton aria-label="delete" onClick={removeRowHandler(index)}>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
);
};
return (
<div className="App">
<TableContainer component={Paper}>
<Table aria-label="spanning table">
<TableHead>
<TableRow>
<TableCell colSpan={2}>
<h2>Invoice lines</h2>
</TableCell>
<TableCell align="right" colSpan={3}>
<IconButton aria-label="add" onClick={addRow}>
<AddBox />
Add Line
</IconButton>
</TableCell>
</TableRow>
<TableRow>
<TableCell align="right">TOTAL</TableCell>
<TableCell align="right">TAX</TableCell>
<TableCell align="right" />
</TableRow>
</TableHead>
<TableBody>
{state.map((row, index) => (
<TableEditRow
key={"TableEditRow" + index}
row={row}
index={index}
changeValueHandler={changeValueHandler}
/>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell align="right">
<span style={{ fontWeight: "bold" }}>
Total: {currencyFormat(tableTotalSum(state))}
</span>
</TableCell>
<TableCell align="right">
<span style={{ fontWeight: "bold" }}>
Tax: {currencyFormat(tableTaxSum(state))}
</span>
</TableCell>
<TableCell />
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</div>
);
}
您可以在https://codesandbox.io/s/issue-material-ui-table-footer-totals-tvv1h中尝试此操作
解决方案
推荐阅读
- react-native - 我如何阻止博览会在网络上运行
- python - 移动 matplotlib 轴以相互匹配
- ios - 第二次调用时 fetchRequest 为空
- javascript - 从另一个异步函数等待 fs.readFile 的正确方法是什么?
- c# - 如何在 WPF 中将 Segoe MDL 字体图标设置为图像源?
- python - Python - 执行 exe 文件时出现 pygame 错误
- macos - macOS:使用“security find-internet-password”检索钥匙串项目的密码和用户名
- gcov - 如何使用 gcovr 工具提高分支覆盖率
- html - 如何交换图标的位置和标签的文本
- javascript - Svelte/Sapper:POST 上的身体是空的