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

React中从Redux数组筛选单条发票数据如何避免返回undefined获取数组结果

问题原因

  1. Array.find() 本身只会返回匹配的对象或者undefined,不符合你需要数组格式返回值的要求;
  2. 直接替换为Array.filter()出现无限打印/渲染的原因是:filter每次执行都会返回新的数组引用,而useSelector默认用引用相等判断值是否变化,所以每次都会触发组件重渲染,进而触发useEffect执行setInvoiceData,再次触发重渲染,形成死循环。

解决方案

方案1:改造useSelector返回逻辑(推荐)

直接在selector中处理find的结果,搭配浅比较避免不必要的重渲染,完全符合你的返回值要求:
首先导入react-redux提供的浅比较工具:

import { useSelector, shallowEqual } from 'react-redux';

修改selector的写法,同时可以删掉冗余的本地state和useEffect逻辑(不需要多存一层状态,直接用selector返回值即可),修改后的完整代码如下:

import React from 'react'
import { Link } from 'react-router-dom'
import backIcon from '../assets/images/icon-arrow-left.svg'
import InvoiceDetailsHeader from './InvoiceDetailsHeader';
import { useSelector, shallowEqual } from 'react-redux';
import InvoiceCardDetails from './InvoiceCardDetails';

const InvoiceDetails = (props) => {
    const id = props.match.params.id;
    // 直接获取符合格式要求的数据:匹配到返回单元素数组,未匹配返回空数组
    const invoiceData = useSelector((state) => {
      const target = state.invoices.find(invoice => invoice._id === id);
      return target ? [target] : [];
    }, shallowEqual); // 加浅比较,数组内容不变就不会触发重渲染

    return (
        <div className="mx-auto px-12 py-16 w-full max-w-3xl">
            <Link to="/" className="text-neutral text-xs"><img className="inline -mt-1 mr-4" src={backIcon} alt="back" /> Go back</Link>
            <InvoiceDetailsHeader data={invoiceData} />
            <InvoiceCardDetails data={invoiceData} />
        </div>
    )
}

export default InvoiceDetails

方案2:坚持用filter的修复方式

如果你一定要用filter实现需求,只要给useSelector加上浅比较参数即可解决无限渲染问题,效果和方案1完全一致:

const invoiceData = useSelector(
  (state) => state.invoices.filter(invoice => invoice._id === id),
  shallowEqual
);

内容的提问来源于stack exchange,提问作者r121

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:27:04