React中修改/删除搜索结果后无法渲染的问题求解
解决搜索状态下待办项删除/编辑后页面不更新的问题
问题描述
我有一个待办项数组和搜索功能,搜索操作会返回过滤后的新数组。但删除或编辑搜索到的项时,页面无法自动渲染这些变化,只有修改搜索关键词后才能正常显示更新。我了解useEffect可以解决该问题,但不清楚回调函数中应写入什么内容,请问该如何解决此问题?
现有代码
ToDoList组件
export const ToDoList = (props: PropsType) => { const [searchQuery, setSearchQuery] = useState('') const searchedItems = useMemo(() => { return props.ToDoData.filter(item => item.text.includes(searchQuery)) }, [searchQuery]) return ( {props.ToDoData.length ? <> <input ... onChange={e => setSearchQuery(e.target.value)} /> <ItemsList ... items={ searchQuery ? searchedItems : props.ToDoData } /> </> : ... } ) }
ItemsList组件
export const ItemsList = (props: PropsType) => { const [editedText, setEditedText] = useState('') const onDeleteItem = (id: number) => { props.dispatch(deleteItem(id)) }, onEditItemMode = (id: number, text: string) => { props.dispatch(setEditMode(true, id)) setEditedText(text) }, onEditText = (id: number) => { props.dispatch(setEditedTextInItem(id, editedText)) props.dispatch(setEditMode(false, id)) setEditedText('') }, onToggleCompletedStatus = (id: number, status: string) => { ... } return ( {props.items.length ? props.items.map((object) => ( <div className="Item" key={object.id} > {props.inEditMode.some((id: number) => id === object.id) ? <> <input value={editedText} onChange={e => { setEditedText(e.currentTarget.value) }} /> <button onClick={() => onEditText(object.id)}> Change text </button> </> : <> <div className="Item__textBlock"> <input type='checkbox' onClick={() => { onToggleCompletedStatus(object.id, object.status)}} /> <span className={ object.status === 'completed' ? 'completed' : 'in process' }> {object.text} </span> </div> <div className="Item__buttonBlock"> <button className="Item__button" disabled={props.inEditMode.length !== 0} onClick={() => onEditItemMode(object.id, object.text)} > <img src={editImg} /> </button> <button className="Item__button" onClick={() => { onDeleteItem(object.id) }} > <img src={removeImg} /> </button> </div> </> } </div> )) : ... } ) }
问题原因
问题出在useMemo的依赖数组配置上:你当前仅将searchQuery作为searchedItems的依赖项,当删除、编辑操作修改了props.ToDoData时,useMemo不会重新执行过滤计算,导致searchedItems始终是旧的过滤结果,ItemsList组件拿到的还是旧数据,因此不会触发页面更新。
解决方案
不需要使用useEffect,只需修正useMemo的依赖数组,把props.ToDoData也加入其中。这样每当原待办数据变化,或者搜索关键词变化时,都会重新计算过滤后的结果,页面就能自动更新。
修改后的ToDoList组件代码
export const ToDoList = (props: PropsType) => { const [searchQuery, setSearchQuery] = useState('') const searchedItems = useMemo(() => { return props.ToDoData.filter(item => item.text.includes(searchQuery)) }, // 新增props.ToDoData作为依赖项 [searchQuery, props.ToDoData]) return ( {props.ToDoData.length ? <> <input ... onChange={e => setSearchQuery(e.target.value)} /> <ItemsList ... items={ searchQuery ? searchedItems : props.ToDoData } /> </> : ... } ) }
额外注意事项
确保你的状态更新是不可变的:删除或编辑待办项时,必须返回新的数组,而不是直接修改原数组。比如:
- 删除操作的reducer示例:
case 'deleteItem': return { ...state, ToDoData: state.ToDoData.filter(item => item.id !== action.payload) }
- 编辑文本的reducer示例:
case 'setEditedTextInItem': return { ...state, ToDoData: state.ToDoData.map(item => item.id === action.payload.id ? {...item, text: action.payload.text} : item ) }
内容的提问来源于stack exchange,提问作者Aaaaaaaaa Aaaaaaaaa
相关产品推荐
相关产品推荐

