You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:36:02