映射数组 prop 后获取多个重复值,然后将映射的值作为 prop 传递给 React 中的另一个组件

问题描述 投票:0回答:1

我正在使用 React 和 Material ui,但我遇到了这个奇怪的错误。

我有一个父订单页面,然后将订单数组传递给订单组件,如下所示:

      <PendingComponent
            {...{pendingOrders}} />

然后在 PendingComponent 中我像这样映射订单数组:

      <Box m="1rem 0 0 0">
      {pendingOrders?.map((order, index) => (
        <Accordion
          key={index}

在这个手风琴内部,还有另一个组件,一个模态,我将订单作为道具传递给它,如下所示:

    {updateSatus && (
                <UpdateOrderStatusModal {...{ order }} />
    )}

现在,当我尝试访问 UpdateOrderStatusModal 组件中的订单值时,发生了奇怪的事情,我没有得到我应该期望的映射订单值的正确值。

像这样,在 PendingComponent 组件中,我当前仅映射 3 个订单,然后将订单传递给 UpdateOrderStatusModal 组件,而不是获取单个订单,而是在我控制台日志时依次打印它们,并且我无法获取我想要进入 UpdateOrderStatusModal 的实际订单:

UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 6:14 PM', step: 0, orderProducts: {…}, …}
UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 6:14 PM', step: 0, orderProducts: {…}, …}
UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 5:15 PM', step: 0, orderProducts: {…}, …}
UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 5:15 PM', step: 0, orderProducts: {…}, …}
UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 5:08 PM', step: 0, orderProducts: {…}, …}
UpdateOrderStatusModal.jsx:27 The order in the modal {status: 'pending', userEmail: '[email protected]', dateCreated: 'Wed, August 16, 2023 at 5:08 PM', step: 0, orderProducts: {…}, …}

我违反了哪些 React 规则?为什么我会出现这种行为? 谢谢你。

更新 - 详细的可重现代码

我在不同的项目中重新创建了相同的问题并遇到了相同的问题。这是该组件的代码。

将一些项目添加到收藏夹后,我为用户提供了一个收藏夹产品页面:

     <ul
                              role="list"
                              className="-my-6 divide-y divide-gray-200"
                            >
                              {products.map((product) => (
                                <li key={product.id} className="flex py-6">
                                  <div
                                    onClick={() => {
                                      setOpenFavourites(false);
                                      navigate(`/product/${product.id}`);
                                    }}
                                    className="hover:cursor-pointer h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200"
                                  >
                                    <img
                                      src={product.images[0]}
                                      alt={product.imageAlt}
                                      className="h-full w-full object-cover object-center"
                                    />
                                  </div>

                                  <div className="ml-4 flex flex-1 flex-col">
                                    <div>
                                      <div className="flex justify-between text-base font-medium text-gray-900">
                                        <h3>
                                          <button
                                            onClick={() => {
                                              setOpenFavourites(false);
                                              navigate(
                                                `/product/${product.id}`
                                              );
                                            }}
                                          >
                                            {product.name}
                                          </button>
                                        </h3>
                                        <p className="ml-4">
                                          $ {product.price}
                                        </p>
                                      </div>
                                      <p className="mt-1 text-sm text-gray-500">
                                        {product.availability}
                                      </p>
                                    </div>
                                    <div className="flex flex-1 items-end justify-between text-sm">
                                      <p className="text-gray-500">
                                        Min Order{" "}
                                        <span className="text-gray-800">
                                          {product.minOrder} Tonne
                                        </span>
                                      </p>

                                      <div className="flex">
                                        <button
                                          type="button"
                                          onClick={() =>
                                            handleRemove(product.id)
                                          }
                                          className="font-medium text-primary hover:text-secondary"
                                        >
                                          Remove
                                        </button>
                                      </div>

                                      <div className="flex">
                                        <button
                                          type="button"
                                          onClick={() => setOpen(true)}
                                          className="font-medium text-primary hover:text-secondary"
                                        >
                                          Open this Modal
                                        </button>
                                      </div>
                                          {open && (<TestModal product={product} />)}
                                    </div>
                                  </div>
                                </li>
                              ))}
                            </ul>

在上面的代码中,如果底部有测试按钮“打开此模态”及其下方的测试模态,则将映射的产品作为道具传递给它。

现在这是 TestModal 代码:

import React from 'react'

const TestModal = ({product}) => {

    console.log("test modal mounted", product.name)

    const investigate = () => {
        console.log("investigate clicked", product.name, product.id)
    }
    return (
        <>
            <div className="justify-center items-center flex overflow-x-hidden overflow-y-auto fixed inset-0 z-50 outline-none focus:outline-none">
                <div className="relative w-auto my-6 mx-auto max-w-3xl">
                    <div className="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-white outline-none focus:outline-none">

                        <div
                            className="
                     items-center justify-end p-6 border-t border-solid border-slate-200 rounded-b"
                        >
                            <button
                                className="text-red-500 background-transparent font-bold uppercase px-6 py-2 text-sm outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
                                type="button"
                            onClick={investigate}
                            >
                                Investigate
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            <div className="opacity-25 fixed inset-0 z-40 bg-black"></div>
        </>
    )
}

export default TestModal

现在在此模式上,假设我在 Potatoes 产品上单击了“打开此模式”,在测试模式中,当我单击“调查”按钮时,我希望将 Potato 产品信息控制台登录到该调查功能中,但这并没有发生,我打印了不同的产品信息,例如草莓,如果我将草莓作为我最喜欢的产品之一,喜欢它总是选择位于映射数组底部的产品,而不是那个我真的点击了。

我还注意到,当我使用模态(显示在其他组件之上的模态组件)时,会发生这种行为,当我使用没有某种 z 索引属性的组件时,它不会执行这种奇怪的行为。

我该如何解决这个问题?

reactjs components mapping rendering react-props
1个回答
0
投票

我没有发现您的代码有任何问题(特别是因为信息有限......)。不过,按照你说的——

...当我控制台日志时,它们都被一个接一个地打印出来

假设您在开发环境中使用严格模式,这是完全正常的。在初始渲染期间重新渲染两次应该可以帮助您更快地找到错误,而 React 只在开发模式下这样做。

违反此规则的组件会出现不可预测的行为并导致错误。为了帮助您意外发现不纯的代码,严格模式会在开发过程中调用您的一些函数(仅那些应该是纯的函数)两次。

https://react.dev/reference/react/StrictMode

© www.soinside.com 2019 - 2024. All rights reserved.