I have a React table which has a column containing delete buttons in each row. When a user clicks on the delete button, a modal pops up asking them to confirm deletion. Once user clicks confirm, the modal closes and the row should be deleted from the table.
I am trying to make it so that I don't have to refresh the page to see the updated table and instead see it right away once the confirm button in the modal is clicked and it closes.
Update: I tried the solution from the comments but I'm getting an error that says deleteCriteriaById
is not defined. Is this supposed to be my reducer function? How would I implement it so that it sends the new array of data? I'm very new with react so I'd appreciate any help
This is my index.js file:
const DataTable = () => {
const dispatch = useDispatch();
const criterias = useSelector((state) => state.questionnaireData.criterias);
useEffect(() => {
if(criterias.length === 0) {
dispatch(fetchCriteria());
}
},[dispatch, criterias])
const mapCriterias = criterias.map((criterias) => ({
id: criterias.criteriaid,
criteria: criterias.criteria
}));
return (
<>
<table>
<tbody>
{mapCriterias.map(item => {
return (
<tr key={item.id}>
<td>{ item.id }</td>
<td>{ item.criteria }</td>
<td><DeleteButton deleteCriteria={dispatch(deleteCriteriaById)} /></td>
</tr>
)
</tbody>
</table>
</>
)
}
My renderDeleteButton (also in index.js):
export const DeleteButton = ({deleteCriteria, id}) => {
let dialogEl=null;
const delete_question = async () => {
try {
const response = await axios.delete(`http://localhost:3001/criteria/${encodeURIComponent(id)}`);
deleteCriteria(id);
} catch (err) {
console.error("delete_question", err.toJSON());
}
}
return (
<>
// modal
<dialog ref={(el) => {
dialogEl = el;
}}>
<div role="document">
<h2>Are you sure you would like to delete this food?</h2>
<p>This action cannot be undone</p>
<form method="dialog">
<div>
<div>
<button type="reset" onClick={()=>dialogEl.close()}>Cancel</button>
</div>
<div>
<button type="del" id="delete_bottom" onClick {()=>delete_question()}>Delete</button>
</div>
</div>
</form>
</div>
</dialog>
// delete button
<button onClick={() =>dialogEl.showModal()} className="delete-btn">
<span role="img">
<Icon icon="gg:trash-empty"/>
</span>
</button>
</>
)
}
My questionnaire.js file:
const initialState = {
criterias: [],
isFetching: false
}
const QuestionnaireSlice = createSlice({
name: "QUESTIONNNAIRE",
initialState,
reducers: {
fetchCriteria: (state) => ({...state, isFetching: true}),
confirmFetchCriteria: (state) => ({ ...state, isFetching: false }),
setCriteria: (state, action) => ({ ...state, criterias: action.payload }),
}
})
Just change window.location.reload(false);
with dispatch(fetchCriteria());
assuming that the delete_question function is inside a React Functional Component.
I think there may be a few optimizations you could make to help achieve what you want.
First I think you may be unnecessarily iterating over the criterias array twice - you should be able to just map once while rendering in your JSX return statement.
Second, your renderDeleteButton function looks like it wants to be a react component (it's returning JSX). So you'll want to implement this a little bit differently to allow the component to take in a delete handler and criteria ID as props.
The delete handler should be a dispatch function that updates your state with the new criterias array that does not include the one with that criteria id.
Something like:
<tbody>
{criterias.map(criteria => {
return (
<tr key={criteria.criteriaid}>
<td>{ criteria.criteriaid }</td>
<td>{ criteria.criteria }</td>
<td><DeleteButton deleteCriteria={dispatch(deleteCriteriaById)} /></td>
</tr>
)
</tbody>
And then your DeleteButton component would look something like:
export const DeleteButton = ({deleteCriteria, id}) => {
const delete_question = async () => {
try {
const response = await axios.delete(`http://localhost:3001/criteria/${encodeURIComponent(key)}`);
deleteCriteria(id)
} catch (error) {
// handle errors
}
}
return (
<>
// modal
<dialog ref={(el) => {
dialogEl = el;
}}>
<div role="document">
<h2>Are you sure you would like to delete this food?</h2>
<p>This action cannot be undone</p>
<form method="dialog">
<div>
<div>
<button type="reset" onClick={()=>dialogEl.close()}>Cancel</button>
</div>
<div>
<button type="del" id="delete_bottom" onClick {()=>delete_question()}>Delete</button>
</div>
</div>
</form>
</div>
</dialog>
// delete button
<button onClick={() =>dialogEl.showModal()} className="delete-btn">
<span role="img">
<Icon icon="gg:trash-empty"/>
</span>
</button>
</>
)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.