【发布时间】:2021-01-26 23:33:34
【问题描述】:
我正在使用material-ui数据表来显示数据,当用户点击任何一行时,用户可以更新数据并通过表单保存。 我使用 react-redux 来维护状态并将更新的行分派给现有数据。我正在通过 redux 将更新的数据返回到我的组件,但 material-ui 表没有使用新数据进行更新。 但是当我刷新页面时,新数据会更新。下面是sn-ps的代码:
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));
Action.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;
Util.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 )
root-reducer.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)
【问题讨论】:
-
此操作:React.useState(allRows) 执行一次,仅在挂载 StaffTable 组件时(以及重启后)。
-
@MaxAlex 所以除了刷新页面别无选择?我对反应很陌生。你有什么建议吗?
-
尝试在后面添加以下内容:React.useState(allRows); React.useEffect(() => { setRows(allRows) }, [allRows]);
-
非常感谢!!有效。你拯救了我的一天。如果你能把它放在答案部分,我会把它标记为已解决?
-
享受它,很高兴得到帮助。
标签: javascript reactjs redux material-ui