javascript - redux 更新数据后 Material UI 表数据刷新
问题描述
我正在使用 material-ui 数据表来显示数据,当用户单击任何行时,用户可以更新数据并通过表单保存。我使用 react-redux 来维护状态并将更新的行分派到现有数据。我正在通过 redux 将更新的数据返回到我的组件,但 material-ui 表没有使用新数据进行更新。但是当我刷新页面时,新数据会更新。以下是代码片段:
const StaffTable = ({selected, allRows, dispatch}) => {
console.log('allRows: ',allRows); // This statement gets executed whenever i dispatch updated data from another component
const classes = useStyles();
const [order, setOrder] = React.useState('asc');
const [orderBy, setOrderBy] = React.useState('sort');
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
const [rows, setRows] = React.useState(allRows);
..
..
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<EnhancedTableToolbar handler={handleFilter}/>
<TableContainer>
<Table
className={classes.table}
aria-labelledby="tableTitle"
size={'small'}
aria-label="enhanced table"
>
<EnhancedTableHead
classes={classes}
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
rowCount={rows.length}
/>
<TableBody>
{stableSort(rows, getComparator(order, orderBy))
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row, index) => {
const isItemSelected = isSelected(row.ppsn);
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
onClick={(event) => handleClick(event, row)}
role="checkbox"
aria-checked={isItemSelected}
tabIndex={-1}
key={row.ppsn}
selected={isItemSelected}
>
<TableCell component="th" id={labelId} scope="row">
{row.disp}
</TableCell>
<TableCell>{row.ppsn}</TableCell>
<TableCell>{row.dob}</TableCell>
<TableCell>{row.town}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Paper>
</div>
);
}
const mapStateToProps = (state) => createStructuredSelector({
selected: selectSelectedStaff,
allRows: selectAllStaffList,
});
export default connect(mapStateToProps)(StaffTable);
调度组件:
const handleSubmit = (event) => {
event.preventDefault();
let clone = JSON.parse(JSON.stringify(selected)); //selected will have updated row of table
dispatch(updateStaff(clone));
动作.js
export const selectAllStaff = () => ({
type: AllStaffActionTypes.SELECT_ALL_STAFF
})
export const updateStaff = (staffToUpdate) => ({
type: AllStaffActionTypes.UPDATE_STAFF,
payload: staffToUpdate
})
}
减速器:
const INITIAL_STATE = {
list: ALL_STAFF //this will have initial set of data rows
}
const allStaffReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case AllStaffActionTypes.SELECT_ALL_STAFF:
return state;
case AllStaffActionTypes.UPDATE_STAFF:
return {
...state,
list: updateStaff(state.list, action.payload),
};
default:
return state;
}
}
export default allStaffReducer;
实用程序.js
export const updateStaff = (staffItems, staffToUpdate) => {
let found = false;
const result = staffItems.map(staff => {
if (staff.ppsn === staffToUpdate.ppsn) {
found = true;
return staffToUpdate;
} else {
return staff;
}
});
if (!found) {
result.push(staffToUpdate);
}
return result;
}
选择器:
import { createSelector } from 'reselect';
const selectAllStaff = state => state.allstaff;
export const selectAllStaffList = createSelector(
[selectAllStaff],
(allstaff) => allstaff.list )
根减速器.js:
import staffReducer from './staff/staff.reducer';
const persistConfig = {
key: 'root',
storage,
whitelist: ['allstaff']
}
const rootReducer = combineReducers({
staff: staffReducer,
allstaff: allStaffReducer,
})
export default persistReducer(persistConfig, rootReducer)
解决方案
此操作:const [rows, setRows] = React.useState(allRows)
仅在挂载 StaffTable 组件时(以及重新启动后)执行一次。
为了反映对 allRows 属性的更改,添加钩子 useEffect:
const StaffTable = ({selected, allRows, dispatch}) => {
console.log('allRows: ',allRows);
const classes = useStyles();
const [order, setOrder] = React.useState('asc');
const [orderBy, setOrderBy] = React.useState('sort');
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
const [rows, setRows] = React.useState(allRows);
React.useEffect(() => { setRows(allRows) }, [allRows]);
推荐阅读
- python - 如果在 python 上具有特定条件,如何降低嵌套的复杂性
- java - Jmeter Beanshell 是否支持从 Kotlin jar 文件调用函数
- salt-stack - Saltstack:如何在 top.sls 中定义“小于版本的包......”
- java - 使用 JPA 时是否可以设置客户端连接属性?
- elasticsearch - Elasticsearch:嵌套文档的聚合组合
- mongodb - 在 aws s3 上上传图像
- reactjs - @apollo/client (react) 为突变创建嵌套的自定义对象类型
- tmux - 创建或附加 Byobu 默认窗口
- docker - 如何从 docker build 获取详细日志(文件列表)
- cassandra - 是否可以在另一个集群上对 cassandra 进行时间点恢复?