reactjs - 如何手动强制父组件在子组件中发生的操作时重新渲染?
问题描述
我正在制作一个 react-redux 应用程序,允许用户提交和审查不同的辣酱。
在我的个人资料页面上,我正在呈现两个列表。用户提交的调味汁之一,以及用户评论过的调味汁之一。我的后端有一个级联删除,当它被删除时,它会删除所有对酱汁的评论。目前,如果用户删除酱汁,个人资料页面上的“酱汁已审核”列表不会更新以删除已删除的酱汁,尽管酱汁已从“酱汁提交”列表中正确删除。单击时,评论列表中的酱汁是死链接,因为该酱汁已被删除。如果您手动刷新页面,死链接就会消失,一切正常。我想知道如何手动触发我的配置文件组件的重新渲染
我的想法是使用我的 Profile 组件中定义的虚拟本地状态变量,如下所示:
const [update, setUpdate] = useState(false)
然后,我会将这些变量作为道具传递给我的删除按钮组件,如下所示:
<Profile>
usersauces.map =>
<div>
list component stuff
<Delete update={update} sauce={sauce} setUpdate={setUpdate}>
然后在我的删除组件中,我有一个句柄删除功能:
const DeleteSauceButton = ({sauce, update, setUpdate}) => {
const handleDelete = async (e) => {
e.preventDefault()
await dispatch(thunk_goDeleteSauce(sauce?.id))
await setUpdate(!update)
console.log("updated", update)
history.push(`/users/${userId}`)
}
我的理解是,删除后子组件中的这种状态变化应该会导致 Profile 父组件的重新渲染,但这并没有发生。当我在设置后 console.log(update) 时,更新仍然是“假”,而不是像我期望的那样“真”。我在这里想念什么?
在我的个人资料组件中,我使用 useSelector 订阅我的状态,如下所示:
const sauceSlice = useSelector(state => state.sauces)
const reviewsSlice = useSelector(state => state.reviews)
const sauces = Object.values(sauceSlice)
const reviews = Object.values(reviewsSlice)
我映射以生成我的列表的列表被过滤如下:
const userReviews = reviews?.filter( review => review?.user_id === userId)
const userSauces = sauces?.filter( sauce => sauce?.user_id === userId)
我更新的删除酱减速器案例是:
case DELETE_SAUCE: {
let newState = { ...state }
delete newState[action.sauce.id]
return { ...newState }
}
而review reducer 类似:
const initialState = {}
const reviewReducer = (state = initialState, action) => {
switch (action.type) {
case LOAD_REVIEWS: {
return { ...state, ...action.reviews }
}
case DELETE_REVIEW: {
let newState = { ...state }
delete newState[action.reviewId]
return { ...newState }
}
case UPDATE_REVIEW: {
if (!action.review) { return { ...state } }
return {
...state,
[action.review.id]: action.review
}
}
default:
return state
}
}
我将 goDeleteSauce thunk 更新为:
export const thunk_goDeleteSauce = (sauce) => async (dispatch) => {
const res = await fetch(`/api/sauces/${sauce.id}`, {
method: 'DELETE',
})
if (res.ok) {
sauce.reviews.forEach((review) => dispatch(deleteReview(review.id)))
dispatch(deleteSauce(sauce))
}
}
审核操作如下所示:
export const deleteReview = (reviewId) => ({
type: DELETE_REVIEW,
reviewId
})
解决方案
您不应该将 await 与 useState 一起使用:
const handleDelete = async (e) => {
e.preventDefault()
await dispatch(thunk_goDeleteSauce(sauce?.id))
setUpdate(value=>!value)
}
推荐阅读
- ios - iOS libusrtcp.dylib 在 NWConcrete_nw_endpoint_flow updatePathWithHandler 上崩溃:
- graph-theory - 证明路径图论的存在
- onnx - 将yolov5模型转换为ONNX并在c++接口上运行
- java - 颤振android工作室(构建失败)
- c# - Column NameStudent 重复列 dataGrid 中数据库表的第一个元素
- vb.net - 如何使用 firebird 参数和条件进行查询
- java - JFrame底部的白边
- unity3d - Unity - 从网格中的数组生成对象导致重复?
- javascript - 如何将图像转换为 url?
- javascript - 如何以角度对嵌套的对象数组进行排序