ReactJS中如何按category id过滤书签卡片 无返回结果排查
问题修复方案
你代码中存在多个逻辑错误,逐一修复即可生效:
问题点汇总
- 自定义的
filterByCategory函数没有返回map遍历后的结果,且你从未将过滤后的书签列表渲染到页面,页面固定渲染的是未过滤的全量书签集合 - 组件内定义的
filterByCategory和props传入的redux action同名,变量覆盖导致你根本没有触发redux的过滤逻辑 - Material UI的
Select组件value属性绑定错误,你传入了整个分类数组,应该绑定当前选中的分类id BookmarkCard组件内的收藏、删除方法没有把当前书签id传入对应的action,导致操作不生效
修正后代码
containers/Bookmarks.js
import React, { useState } from 'react' import BookmarkCard from './BookmarkCard' import BookmarkForm from '../components/BookmarkForm' import CategoryForm from '../components/CategoryForm' import Select from '@material-ui/core/Select' import MenuItem from '@material-ui/core/MenuItem' import { connect } from 'react-redux' // 改名避免和本地变量冲突 import { filterByCategory as dispatchFilterByCategory } from '../actions' const Bookmarks = (props) => { // 本地存储选中的分类id,也可以根据需求存在redux中 const [selectedCategoryId, setSelectedCategoryId] = useState('') const renderBookmarkCollection = () => { // 未选中分类时返回全量,选中时返回过滤结果 const filteredBookmarks = selectedCategoryId ? props.bookmarks.filter(bookmark => bookmark.category_id == selectedCategoryId) : props.bookmarks return filteredBookmarks.map(bookmark => { return <BookmarkCard key={bookmark.id} {...bookmark}/> }) } const handleCategoryChange = (e) => { const categoryId = e.target.value setSelectedCategoryId(categoryId) // 需要同步过滤状态到redux就调用以下方法 props.filterByCategory(categoryId) } return ( <div className="bookmarks-container"> <br></br> <BookmarkForm /> <CategoryForm/> <form className="filter-category"> <p>FILTER BY CATEGORY</p> <Select id="category-input" value={selectedCategoryId} onChange={handleCategoryChange} > {/* 可选增加全部分类选项 */} <MenuItem value="">全部分类</MenuItem> {props.categories.map(category => { return ( <MenuItem key={category.id} name={category.name} value={category.id} >{category.name}</MenuItem> ) })} </Select> </form> <br></br> {renderBookmarkCollection()} </div> ) } const mapStateToProps = (currentState) => { return { bookmarks: currentState.bookmarks.bookmarks, categories: currentState.categories.categories } } const mapDispatchToProps = (dispatch) => { return { filterByCategory: (id) => dispatch(dispatchFilterByCategory(id)) } } export default connect(mapStateToProps, mapDispatchToProps)(Bookmarks)
containers/BookmarkCard.js
import React from 'react' import Button from "@material-ui/core/Button" import DeleteIcon from "@material-ui/icons/Delete" import FavoriteIcon from "@material-ui/icons/Favorite" import { useHistory } from 'react-router-dom' import { connect } from 'react-redux' import { deleteBookmark, favoriteBookmark } from '../actions/index' const BookmarkCard = (props) => { const history = useHistory() const handleFavorite = () => { // 传入当前书签id到action props.favoriteBookmark(props.id) history.push('/bookmarks') } const handleDelete = () => { // 传入当前书签id到action props.deleteBookmark(props.id) history.push('/bookmarks') } return ( <div className="bookmark-card" id={`bookmark-${props.id}`}> <h2 className="bookmark-headline">{props.headline}</h2> <p className="bookmark-description">{props.description}</p> <p className="bookmark-web-url" >{props.web_url}</p> <Button id={props.id} onClick={handleFavorite} className="favorite-button" startIcon={<FavoriteIcon/>}> </Button><br></br> <Button id={props.id} size="small" startIcon={<DeleteIcon />} onClick={handleDelete} className="delete-button"> </Button><br></br> </div> ) } const mapDispatchToProps = (dispatch) => { return { deleteBookmark: (id) => dispatch(deleteBookmark(id)), favoriteBookmark: (id) => dispatch(favoriteBookmark(id)) } } export default connect(null, mapDispatchToProps)(BookmarkCard)
内容的提问来源于stack exchange,提问作者Adri Dipietro
相关产品推荐
相关产品推荐

