【问题标题】:navigating results in changes of state in react after passing state to Link component将状态传递给 Link 组件后,导航导致反应中的状态变化
【发布时间】:2022-01-10 04:50:32
【问题描述】:

我正在制作一个购买发票应用程序。

现在应用中有两个页面。
一个是创建新发票的页面,可以保存到数据库并导出到 Excel 文件。 (Invoice.js)
另一个是发票列表的页面,每个发票都有修改/删除按钮。 (Invoices.js)

当列表的修改按钮中的发票被点击时,它会链接到创建页面,并且发票数据是一个状态,作为参数传递。

无需将发票数据传递到创建页面,导航完全没有问题。
但是,我将'state'属性放入Link组件后,出现以下错误。

Invoices.js:21
未捕获的类型错误:无法读取未定义的属性(正在读取“子字符串”)
在 Invoices.js:21:1
在 Array.filter()
在 Invoices.js:21:1
在 invokePassiveEffectCreate (react-dom.development.js:23487:1)
在 HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
在 Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
在 invokeGuardedCallback (react-dom.development.js:4056:1)
在 flushPassiveEffectsImpl (react-dom.development.js:23574:1)
在不稳定的_runWithPriority (scheduler.development.js:468:1)
在 runWithPriority$1 (react-dom.development.js:11276:1)

这是我的源代码

// App.js

const App = () => {
  return (
    <BrowserRouter>
      <Container maxWidth="lg">
        <NavBar />
        <Routes>
          <Route path="/" exact element={<Navigate to="/invoice/create" />} />
          <Route path="/invoice/create" element={<Invoice />} />
          <Route path="/invoice/view" element={<Invoices />} />
        </Routes>
      </Container>
    </BrowserRouter>
  );
};

// Invoices.js

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getInvoices } from '../../actions/invoices';
import InvoiceRow from './InvoiceRow';

const Invoices = () => {
  const [month, setMonth] = React.useState(new Date().getMonth() + 1);

  const invoices = useSelector((state) => state.invoices);
  const dispatch = useDispatch();

  const [invoicesCurrent, setInvoicesCurrent] = React.useState([]);

  useEffect(() => {
    dispatch(getInvoices());
  }, [dispatch]);

  useEffect(() => {
    setInvoicesCurrent(invoices.filter((invoice) => Number(invoice.invoiceDate.substring(5, 7)) === month));
  }, [invoices, month, dispatch]);
  
  ...

  // Link component used: invoice is the one of invoice in invoices state
    <Link to='/invoice/create'
          state={{ ...invoice }}>
      <Button>Modify</Button>
    </Link>

// 发票.js

const InvoiceComponent = () => {
  const location = useLocation();
  const invoice = location.state;
  const [company, setCompany] = useState(invoice ? invoice.company : '');
  const [employee, setEmployee] = useState(invoice ? invoice.employee : '');
  const [invoiceDate, setInvoiceDate] = useState(invoice ? invoice.invoiceDate : new Date());
  const [orderId, setOrderId] = useState(invoice ? invoice.orderId : '');
  const [companyTel, setCompanyTel] = useState(invoice ? invoice.companyTel : '');
  const [companyFax, setCompanyFax] = useState(invoice ? invoice.companyFax : '');

  const items = useSelector((state) => state.items);
  const dispatch = useDispatch();

  useEffect(() => {
    const last = document.getElementById(`row-${items.length - 1}-0`);
    if (last != null) last.focus();
  }, [items.length]);

  useEffect(() => {
    if (invoice) {
      dispatch(updateItems(invoice.items));
    }
  }, [dispatch, invoice]);

  ...

我必须分享当前的应用行为。

  1. 点击“修改”按钮后,创建页面会加载发票数据。
  2. 然后使用“返回”、“前进”导航,或单击两个页面中的任何一个的链接都会显示上面的错误。
  3. 在 Invoices.js 中调用 setInvoicesCurrent 的 useEffect 挂钩中,
    当我 console.log(invoices) 时,它不是一个发票数组,而是一个其他状态(项目)的数组,在 Invoice.js 中使用
  4. 刷新页面会重置所有内容。

在导航时是否有管理 redux store 的指南?

// console.log(invoices) 在 useEffect 调用 setInvoicesCurrent
// 正常打开
发票
(6) [{…}, {…}, {…}, {…}, {…}, {...}]
0:{_id:'1',公司:'cmp1',员工:'e1',invoiceDate: '2022-01-07T05:14:15.482Z', orderId: '', ...}
1: {_id: '2', 公司: “cmp2”,员工:“e1”,发票日期:“2022-01-07T05:14:15.482Z”, orderId:'',...}
2:{_id:'3',公司:'comp3',员工:'e1', invoiceDate: '2022-01-07T05:14:15.482Z', orderId: '', ...}
3: {_id: “4”,公司:“comp4”,员工:“e1”,发票日期: '2022-01-07T05:14:15.482Z', orderId: '', ...}
4: {_id: '5', 公司: “comp5”,员工:“e1”,发票日期:“2022-01-07T05:14:15.482Z”, orderId:'',...}
5:{_id:'6',公司:'comp6',员工:'e1', invoiceDate: '2022-01-07T13:10:56.380Z', orderId: '', ...}
长度: 6 [[原型]]:数组(0)

每个数组都有以下数据
0:
公司:“cmp1”
公司传真:“1222222222”
公司电话:“122331232”
员工: "e1"
invoiceDate: "2022-01-07T05:14:15.482Z"
项目: 数组(2)
0:{名称:'item1',规格:'spec1',数量:1,价格:10000, 总计:10000,...}
1:{名称:'item2',规格:'spec2',数量:20, 价格:1000,总计:20000,...}
长度:2
[[原型]]: Array(0)
modifiedOn: "2022-01-07T05:25:14.771Z"
orderId: ""
__v: 0
_id:“1”

// console.log(invoices) 发生错误时
发票
(6) [数组(2),数组(2),数组(2),数组(2),数组(2),数组(2)]
0: 数组(2)
0:{名称:'item1',规格:'spec1',数量:1,价格: 10000,总数:10000,...}
1:{名称:'item2',规格:'spec2',数量: 20,价格:1000,总计:20000,...}
长度:2

[[原型]]: Array(0)
1: Array(2)
0: {name: 'item1', 规格:'spec1',数量:1,价格:10000,总计:10000,...}
1:{名称: 'item2',规格:'spec2',数量:20,价格:1000,总计:20000,...}

长度:2
[[原型]]: Array(0)
2: (2) [{…}, {…}]
3: (2) [{…}, {…}]
4: (2) [{…}, {…}]
5: (2) [{…}, {…}]
长度:6
[[原型]]:数组(0)

【问题讨论】:

  • 你正在传播到路由状态的invoice的值是多少? invoiceInvoices.js 中声明的位置在哪里?似乎缺少一些代码,您可以更新以提供完整且可重现的代码示例吗? stackoverflow.com/help/minimal-reproducible-example

标签: reactjs redux react-router-dom


【解决方案1】:

你不应该将数组解构为一个对象,它会创建一个对象。

像下面这样使用

// Invoices.js
<Link to="/invoice/create" state={{ invoice }}>
  <Button>Modify</Button>
</Link>;

// Invoice.js
const { invoice } = location.state;

注意:

const a = [1,2,3];
console.log({...a}); // {0: 1, 1: 2, 2: 3}

【讨论】:

  • 谢谢您,先生。但问题仍然存在。它在加载 Invoice.js 时工作,但是当我“返回”或单击 Invoices.js 的链接时,“发票”状态变为相同“项目”数组的数组。
  • 因为你在做dispatch(updateItems(invoice.items));,
  • 为什么更新项目状态会影响发票状态?那么我应该在导航到发票页面时重置调度功能吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 2019-07-07
  • 2019-03-07
  • 1970-01-01
  • 2020-01-09
相关资源
最近更新 更多