当前位置: 首页 > 知识库问答 >
问题:

Next.js警告:警告:列表中的每个孩子都应该有一个唯一的“key”道具[重复]

邢昂然
2023-03-14

我正在使用Nextjs开发一个电子商务网站,并正在查看myCart页面(订购物品列表)

代码为'http://localhost:5000/myCart'如下所示:myCart页面

import React, { useState, useEffect } from 'react';
import styles from '../public/css/MyCart.module.scss';
import Container from 'react-bootstrap/Container';
import Link from 'next/link';
import Layout from '../components/Layout';
import OrderCard from '../components/OrderCard';
import Router from 'next/router';
import fetch from 'isomorphic-unfetch';

// let customerName = '';
// let customerMail = '';
// let data;
let key;
// let dta2;
let arr1 = [];

function orderCard(arr1) {
  return (
    <>
      <div className={styles.item_group} key={arr1._id}>
        <OrderCard
          id={arr1._id}
          item={arr1.itemName}
          menu={String(arr1.menuId)}
          img={arr1.itemPic}
          summary={arr1.summary}
          size={String(arr1.itemSize)}
          qtty={String(arr1.qtty)}
          price={String(arr1.itemPrice)}
        />
      </div>
    </>
  );
}

function MakeGetRequest(props) {
  const arr1 = props.bpi.myList;
  const customerMail = props.bpi.userMail;
  const customerName = props.bpi.userName;

  console.log(customerMail, customerName);
  console.log(`myList: ${arr1}`);

  function handleCheckout(e) {
    e.preventDefault();
    e.target.textContent = 'Processing...';
    Router.replace('/checkout_form');
  }

  if (!arr1 || arr1 === 'undefined') {
    // console.log(`In myCart makeGetRequest with arr1 ${arr1}`);
    return (
      <div>
        <Layout title="My Cart">
          {/* <Link href="/">
            <a className={styles.toHome}>&larr; Back to home </a>
          </Link> */}
          <Container className={styles.container}>
            <main className={styles.main}>
              <h1
                className={styles.heading_secondary}
                id={styles.heading_secondary}
              >
                Your cart is empty. Please click on back to home and select
                items.
              </h1>
            </main>
          </Container>
        </Layout>
      </div>
    );
  }

  const arrLen = arr1.length;
  // dta2 = arrLen;

  // console.log(dta2);

  const qttyTotal = arr1.reduce(
    (totalQtty, arrQty) => totalQtty + arrQty.qtty,
    0
  );

  const amtTotal = arr1.reduce((prev, curr) => {
    return prev + curr.qtty * curr.itemPrice;
  }, 0);

  // useEffect(() => {
  //   dta2 = arrLen;
  // }, [arrLen]);

  return (
    <div>
      <Layout title="My Cart">
        <div>
          <div className={styles['customer-details']}>
            <h3 className={styles.cartName}>Cart of {customerName}</h3>
            <p className={styles['customer-details']}>{customerMail}</p>
          </div>
          <Container className={styles.container}>
            <section className={styles.section_cartList}>
              {/* <div className={styles.row0}> */}
              <div className={`${styles['col_1_of_2']} ${styles['col-1']}`}>
                <div className={`${styles['grid']} ${styles['menu-item']}`}>
                  <div key="{item}"> {arr1.map(orderCard)}</div>

                  {/* {arr1.map(orderCard)} */}
                </div>
              </div>
              <div className={`${styles['col_1_of_2']} ${styles['col-2']}`}>
                <div className={styles.heading}>
                  <h2
                    className={styles.heading_secondary}
                    id={styles.heading_secondary}
                  >
                    SUMMARY
                  </h2>
                  <h3 className={styles.itemsTotalP}>No. of items</h3>
                  <h3 className={styles.itemsTotal}>{arrLen}</h3>
                  <h3 className={styles.qttyTotalP}>No. of dishes</h3>
                  <h3 className={styles.qttyTotal}>{qttyTotal}</h3>
                  <h3 className={styles.amtTotalP}>Total amount (US$):</h3>
                  <h3 className={styles.amtTotal}>{amtTotal}</h3>
                </div>
                <button
                  className={`${styles['label']} ${styles['btnCart']}`}
                  type="button"
                  onClick={handleCheckout}
                >
                  CHECKOUT
                </button>
              </div>
            </section>
          </Container>
        </div>
      </Layout>
    </div>
  );
}

MakeGetRequest.getInitialProps = async (req, res, ctx) => {
  res = await fetch('http://localhost:5000/api/users/myCart');

  let data = await res.json();

  console.log(`In getInitialProps: ${data.userMail}`);

  return { bpi: data };
};

export default MakeGetRequest;

我在导航栏中有一个购物车图标。当我点击它时,我被导航到我的购物车页面。已排序的列表将正确显示。但是在Dev工具中检查控制台时,我看到下面给出的警告。

同样,当我点击购物车图标时,页面会刷新并正确显示。此时,浏览器读取http://localhost:5000/myCart.这是相同的URL,同时单击购物车。

但令人惊讶的是,如果我通过单击URL空间附近的图标来刷新浏览器,页面将无法正确显示。检查时,我发现后端的myList没有传输到前端。

我的后端代码:

async function displayCartDetails(req, res, next) {
  // 1) Getting token and check if it's there

  if (!req.cookies.token) {
    return res.status(423).json({
      status: 'Failed',
      msg: 'You are not logged in. Please login.',
    });
  }

  const tokenValue = req.cookies.token;
  // console.log(`token found ${tokenValue}`);

  const decoded = jwt.verify(tokenValue, process.env.JWT_SECRET);

  const userId = decoded._id;

  // console.log(`userId: ${userId}`);

  const user = await User.findById(decoded._id);

  console.log(`user: ${user}`);

  cartSelected = user.cartId;
  // console.log(`In userController cartSelected: ${cartSelected}`);

  const userName = user.name;
  // console.log(`In userController: ${userName}`);

  const userMail = user.email;
  //   console.log(`In userController: ${userMail}
  // `);

  myList = await Cart.find({ _id: { $in: cartSelected } });

  if (!myList) {
    return res.status(401).json({
      msg: 'Some error occurred. Please try again later.',
    });
  }

  console.log(`myList: ${myList}`);

  // const { myList, userName, userMail } = user;

  return res.status(201).json({
    status: 'success',
    myList: myList,
    userName,
    userMail,
    user: { myList, userName, userMail },
    // token,
  });
}


如果我再次单击购物车图标,页面将正确显示。

始终显示以下警告。

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `MakeGetRequest`. See ...fb.me/react-warning-keys for more information.
    in Fragment (created by MakeGetRequest)
    in MakeGetRequest (at _app.js:5)
    in MyApp
    in ErrorBoundary (created by ReactDevOverlay)
    in ReactDevOverlay (created by Container)
    in Container (created by AppContainer)
    in AppContainer
    in Root
overrideMethod @ react_devtools_backend.js:2430
printWarning @ react.development.js?72d0:315
error @ react.development.js?72d0:287
validateExplicitKey @ react.development.js?72d0:1630
validateChildKeys @ react.development.js?72d0:1656
createElementWithValidation @ react.development.js?72d0:1806
MakeGetRequest @ myCart.js?4849:105
renderWithHooks @ react-dom.development.js?61bb:14803
mountIndeterminateComponent @ react-dom.development.js?61bb:17482
beginWork @ react-dom.development.js?61bb:18596
beginWork$1 @ react-dom.development.js?61bb:23179
performUnitOfWork @ react-dom.development.js?61bb:22154
workLoopSync @ react-dom.development.js?61bb:22130
performSyncWorkOnRoot @ react-dom.development.js?61bb:21756
eval @ react-dom.development.js?61bb:11089
unstable_runWithPriority @ scheduler.development.js?3069:653
runWithPriority$1 @ react-dom.development.js?61bb:11039
flushSyncCallbackQueueImpl @ react-dom.development.js?61bb:11084
flushSyncCallbackQueue @ react-dom.development.js?61bb:11072
scheduleUpdateOnFiber @ react-dom.development.js?61bb:21199
updateContainer @ react-dom.development.js?61bb:24373
legacyRenderSubtreeIntoContainer @ react-dom.development.js?61bb:24774
render @ react-dom.development.js?61bb:24840
renderReactElement @ index.tsx?8abf:473
doRender @ index.tsx?8abf:719
_callee2$ @ index.tsx?8abf:360
tryCatch @ runtime.js?96cf:63
invoke @ runtime.js?96cf:293
eval @ runtime.js?96cf:118
asyncGeneratorStep @ asyncToGenerator.js?c973:3
_next @ asyncToGenerator.js?c973:25
eval @ asyncToGenerator.js?c973:32
eval @ asyncToGenerator.js?c973:21
render @ index.js:425
subscription @ index.tsx?8abf:318
notify @ router.ts?35b8:1228
set @ router.ts?35b8:1019
_callee$ @ router.ts?35b8:816
tryCatch @ runtime.js?96cf:63
invoke @ runtime.js?96cf:293
eval @ runtime.js?96cf:118
asyncGeneratorStep @ asyncToGenerator.js?c973:3
_next @ asyncToGenerator.js?c973:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?c973:13
_next @ asyncToGenerator.js?c973:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?c973:13
_next @ asyncToGenerator.js?c973:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?c973:13
_next @ asyncToGenerator.js?c973:25
eval @ asyncToGenerator.js?c973:32
eval @ asyncToGenerator.js?c973:21
change @ router.js:727
push @ router.ts?35b8:571
instance.<computed> @ router.ts?06ff:165
linkClicked @ link.tsx?5e4b:145
onClick @ link.tsx?5e4b:317
callCallback @ react-dom.development.js?61bb:188
invokeGuardedCallbackDev @ react-dom.development.js?61bb:237
invokeGuardedCallback @ react-dom.development.js?61bb:292
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?61bb:306
executeDispatch @ react-dom.development.js?61bb:389
executeDispatchesInOrder @ react-dom.development.js?61bb:414
executeDispatchesAndRelease @ react-dom.development.js?61bb:3278
executeDispatchesAndReleaseTopLevel @ react-dom.development.js?61bb:3287
forEachAccumulated @ react-dom.development.js?61bb:3259
runEventsInBatch @ react-dom.development.js?61bb:3304
runExtractedPluginEventsInBatch @ react-dom.development.js?61bb:3514
handleTopLevel @ react-dom.development.js?61bb:3558
batchedEventUpdates$1 @ react-dom.development.js?61bb:21871
batchedEventUpdates @ react-dom.development.js?61bb:795
dispatchEventForLegacyPluginEventSystem @ react-dom.development.js?61bb:3568
attemptToDispatchEvent @ react-dom.development.js?61bb:4267
dispatchEvent @ react-dom.development.js?61bb:4189
unstable_runWithPriority @ scheduler.development.js?3069:653
runWithPriority$1 @ react-dom.development.js?61bb:11039
discreteUpdates$1 @ react-dom.development.js?61bb:21887
discreteUpdates @ react-dom.development.js?61bb:806
dispatchDiscreteEvent @ react-dom.development.js?61bb:4168
Show 13 more frames

请求适当的指导。当做

共有1个答案

濮阳祯
2023-03-14

您没有向片段添加密钥,因此映射的“orderCard”组件在最外部的元素上没有密钥。试着用这样的键控片段替换你的片段。

  return (
    <React.Fragment key={arr1._id}>
      <div className={styles.item_group}>
        <OrderCard
          id={arr1._id}
          item={arr1.itemName}
          menu={String(arr1.menuId)}
          img={arr1.itemPic}
          summary={arr1.summary}
          size={String(arr1.itemSize)}
          qtty={String(arr1.qtty)}
          price={String(arr1.itemPrice)}
        />
      </div>
    </React.Fragment>
  );
}```
 类似资料:
  • 问题内容: 我正在使用Google Books API构建应用,并且似乎正在向列表中的每个孩子传递唯一键,但是错误不会消失。我一定在做错事,但不确定。 请注意,在返回const books之后,我有一个console.log(book.id),它将在控制台中显示所有10个唯一的id键。但是,当我尝试使用key = {book.id}将其传递给该组件的子组件时,会出现此错误。 问题答案: 在需要去最

  • 我正在使用GoogleBooksAPI构建一个应用程序,我似乎正在向列表中的每个孩子传递一个唯一的密钥,但错误不会消失。我一定是做错了什么,但我不知道是什么。 注意,在const books中返回后,我有一个控制台。日志(book.id),它将在控制台中显示所有10个唯一的id键。但是当我试图使用key={book.id}将它传递给这个组件的子组件时,我得到了这个错误。

  • 在这个简单的React应用程序中,我不明白为什么我会收到以下警告信息: 警告:列表中的每个孩子都应该有一个唯一的“键”道具。 对我来说,似乎我把密钥放在了正确的位置,形式为key={item.login.uuid} 我怎样才能摆脱警告信息?把钥匙放在哪里合适? 应用程序。js 列表js

  • 我对如何创建一个简单的todo应用程序的反应和探索方式还不熟悉。我当前收到错误“警告:列表中的每个孩子都应该有一个唯一的“键”道具。”一切似乎都很好,但我一定是做错了什么。 如果有人能帮上忙,那就br太好了/解释为什么会发生这个错误,那就太好了。

  • 为什么它向我显示这个错误? 我有一个应用程序是在我的react native Studio中使用npx react native init myProyect创建的。 我正在测试使用“styled components/native”添加样式的方法。 我想展示不同的公司,他们的名字,地址,公司类型的图标,公司的形象和评级明星。 我为星星添加了一个svg图像。对于公司映像,出于测试目的,我已经通过网

  • 我写了一个BlackJack游戏,但是在我从卡片API中查询API后,卡片从未显示在屏幕上。我有控制台记录了玩家甲板和交易甲板,它有卡片数据,但没有显示。 错误如下:index.js:1375警告:列表中的每个子级都应该有一个唯一的“键”道具。 检查的渲染方法。参见https://reactjs.org/link/warning-keys了解更多信息。在黑杰克(http://localhost:3