I'm doing a table with delete and edit option and when I open a modal my modal has a black background. I found the problem and it is because when I click to open the modal it open multiple times. If I have 10 rows the modal open 10 times.
I'm using React-table-v7 and redux for my modal states.
useTableHook.js
const resourcesColumns = useMemo(() => [
{
Header: 'delete',
accessor: () => 'delete',
disableSortBy: true,
Cell: ({row}) => <div onClick={(event) => event.stopPropagation()}>
<DeleteModal />
</div>
}
], [resourceData]);
useEffect(() => {
hideColumns();
setResourceData(data);
}, [data]);
My tableView.jsx
<tbody {...getTableBodyProps()} >
{loading
? <tr className="text-center">
<td colSpan="5">
<LoadingComponent />
</td>
</tr>
: page.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} className="tb-row" onClick={() => showSelectedRow(row)} key={row}>
{row.cells.map((cell, index) => <td
{...cell.getCellProps()}
key={index}
className={`${index === 0 ? 'tb-body-txt-left py-2 px-2' : 'tb-body-txt'}`}
>
{cell.render('Cell')}
</td>
)}
</tr>
);
})
}
</tbody>
i'm using a hook for select the state
const modalState = () => {
const ModalState = useSelector((state) => state.modal.isOpen);
return ModalState;
};
my slice for modals
const modalSlice = createSlice({
name: 'modal',
initialState: {isOpen: false},
reducers: {
openModal: (state, action) => {
state.isOpen = true;
},
closeModal: (state, action) => {
state.isOpen = false;
}
}
});
export const {reducer} = modalSlice;
export default modalSlice.actions;
my modal view
<>
<i className="fa fa-trash-can text-primary ZoomIcon" onClick={handlers.opened} />
<Modal show={show} onHide={handlers.closed} className="modalPosition">
<Modal.Header closeButton>
<Modal.Title>Atención !!</Modal.Title>
</Modal.Header>
<Modal.Body>Confirme que desea eliminar el recurso </Modal.Body>
<Modal.Footer className="modalFooter">
<Button variant="light" onClick={handlers.closed} autoFocus={true}>Close</Button>
<Button variant="primary" onClick={handlers.closed} autoFocus={true}>
<i className="fa fa-check" aria-hidden="true"></i>Confirmar</Button>
</Modal.Footer>
</Modal>
</>
here i pass my hook for the show property
const modalState = useDeletehook();
<DeleteModal show={modalState}/>
Do you know how can I fix this problem?
The main issue is that you've only a single modal.isOpen
state and multiple modals.
const modalSlice = createSlice({
name: 'modal',
initialState: { isOpen: true },
reducers: {
openModal: (state, action) => {
state.isOpen = true;
},
closeModal: (state, action) => {
state.isOpen = false;
}
}
});
When state.modal.isOpen
is true then all modals are opened.
You want to set some isOpen
state to indicate that a specific modal should be shown. You can do this by using some id
value that is related to the row data.
const modalSlice = createSlice({
name: 'modal',
initialState: {
isOpen: null
},
reducers: {
openModal: (state, action) => {
state.isOpen = action.payload;
},
closeModal: (state, action) => {
state.isOpen = null;
}
}
});
To open a specific modal dispatch the openModal
action and pass the id of a specific modal you want opened.
dispatch(modalSlice.openModal(rowEl.id));
dispatch(modalSlice.closeModal());
<DeleteModal show={modalState.isOpen === rowEl.id}/>