首页 > 解决方案 > 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)

标签: javascriptreactjsreduxmaterial-ui

解决方案


此操作: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]); 

推荐阅读