在不刷新页面的情况下从React表中删除行



我有一个React表,它有一列,每行都包含删除按钮。当用户点击删除按钮时,会弹出一个模式,要求他们确认删除。一旦用户单击confirm,模态就会关闭,并且应该从表中删除该行。

我正在努力做到这一点,这样我就不必刷新页面来查看更新后的表,而是在单击模式中的确认按钮并关闭后立即查看它。

更新:我尝试了评论中的解决方案,但我收到一个错误,上面写着Uncaught TypeError: Cannot destructure property 'deleteFood' of '_ref' as it is undefined.我该如何修复这个错误?我对react很陌生,所以我很感激任何帮助!

这是我的index.js文件:

const DataTable = () => {
const dispatch = useDispatch();
const foods = useSelector((state) => state.foodData.foods);
useEffect(() => {
if(foods.length === 0) {
dispatch(fetchFood());
}
},[dispatch, foods])
const mapFoods = foods.map((foods) => ({
id: foods.foodid,
food: foods.food
}));
return (
<>
<table>
<tbody>
{foods.map(food=> {
return (
<tr key={food.foodid}>
<td>{ food.id }</td>
<td>{ food.food}</td>
<td><DeleteButton deleteFood={dispatch(deleteFoodById)} id={food.foodid} /></td>
</tr>
)
</tbody>
</table>
</>
)
}

我的renderDeleteButton(也在index.js中(:

export const DeleteButton = ({deleteFood, id}) => {
let dialogEl=null;
const delete_food = async () => {
try {
const response = await axios.delete(`http://localhost:3001/food/${encodeURIComponent(id)}`);
deleteFood(id);
} catch (err) {
console.error("delete_food", 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>
</>
)
}

我的问卷.js文件:

const initialState = {
foods: []
}
const FoodSlice = createSlice({
name: "FOOD",
initialState,
reducers: {
setFood: (state, action) => ({ ...state, foods: action.payload }),
deleteFoodById: (state, action) => ({ ...state, foods: state.foods.filter(({foodid}) => foodid !== action.payload) })
}
})

假设delete_question函数在React Functional Component中,只需将window.location.reload(false);更改为dispatch(fetchCriteria());即可。

我认为可能有一些优化可以帮助实现您想要的。

首先,我认为您可能不必要地对criterias数组进行两次迭代——在JSX return语句中进行渲染时,您应该能够只映射一次。

其次,renderDeleteButton函数看起来像是想成为一个react组件(它正在返回JSX(。因此,您需要以不同的方式实现这一点,以允许组件将删除处理程序和条件ID作为道具。

删除处理程序应该是一个调度函数,它用新的criterias数组更新您的状态,该数组不包括具有该条件id的数组。

类似于:

const DeleteButton = ({id}) => {
const dispatch = useDispatch();
let dialogEl=null;
const delete_question = async () => {
try {
const response = await axios.delete(`http://localhost:3001/criteria/${encodeURIComponent(id)}`);
dispatch(deleteCriteriaById(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>
</>
)
}
const DataTable = () => {
const dispatch = useDispatch();
const criterias = useSelector((state) => state.criterias);
useEffect(() => {
if(criterias.length === 0) {
dispatch(fetchCriteria());
}
},[dispatch, criterias])
return (
<>
<table>
<tbody>
{criterias.map(criteria=> {
return (
<tr key={criteria.criteriaid}>
<td>{ criteria.criteriaid }</td>
<td>{ criteria.criteria }</td>
<td><DeleteButton id={criteria.criteriaid} /></td>
</tr>
)})}
</tbody>
</table>
</>
)
}

deleteCriteriaById可能看起来像:

deleteCriteriaById: (state, action) => ({...state, 
criterias: state.criterias.filter(({criteriaid}) => criteriaid !== action.payload)
}),

最新更新