ike81818
@ike81818

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Warning: Each child in a list should have a unique "key" prop. の対処方法

解決したいこと

下記のようなページネーションのUIをNext.jsのコンポーネントで作成しました。
スクリーンショット 2022-07-03 20.28.04.png

すると、Chromeのデベロッパーツールのコンソール画面に、
Warning: Each child in a list should have a unique "key" prop.
スクリーンショット 2022-07-03 20.23.00.png
というエラーが発生します。

配列に対するmap関数を適用する場面での書き方はわかるのですが、
今回は、このような関数を使っていないので、
どのようにすればよいかわかりません。

対処方法を教えていただければ幸いです。

エラーが発生しているコード

components/paging.js
import styles from "../styles/Home.module.css";

const Paging = ({
  pageIncrement,
  pageDecrement,
  pageChange,
  page,
  pageCount,
}) => {
  let pageCount2 = pageCount;
  if (pageCount2 > 1000) {
    pageCount2 = 1000;
  }
  let haba = 2;
  let startpage = page - haba;
  if (startpage < 2) {
    startpage = 2;
  }
  let endpage = page + haba;
  if (endpage >= pageCount2) {
    endpage = pageCount2 - 1;
  }
 
  const items = [];

  if (page > 2) {
    items.push(
      <button className={styles.prevPageButton} onClick={() => pageDecrement()}>
        前へ
      </button>
    );
  }

  if (pageCount2 > 1) {
    items.push(
      <button
        className={page == 1 ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(1)}
      >
        1
      </button>
    );
  }

  if (startpage >= 3) {
    items.push(<span className={styles.pageSpan}>...</span>);
  }
  for (let i = startpage; i <= endpage; i++) {
    items.push(
      <button
        className={i == page ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(i)}
      >
        {i}
      </button>
    );
  }
  if (endpage <= pageCount2 - 2) {
    items.push(<span className={styles.pageSpan}>...</span>);
  }
  if (pageCount2 > 1) {
    items.push(
      <button
        className={page == pageCount2 ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(pageCount2)}
      >
        {pageCount2}
      </button>
    );
  }
  if (page < pageCount2) {
    items.push(
      <button className={styles.nextPageButton} onClick={() => pageIncrement()}>
        次へ
      </button>
    );
  }

  return (
    <>
      <div>{items}</div>
      <div className={styles.pagination2}>
        {pageCount2 > 0 && `${page} / ${pageCount2} ページ`}
      </div>
    </>
  );
};

export default Paging;

下記のように、keyとして、let k;を導入すると、warningが出なくなりました。

components/paging.js
import styles from "../styles/Home.module.css";

const Paging = ({
  pageIncrement,
  pageDecrement,
  pageChange,
  page,
  pageCount,
}) => {
  let pageCount2 = pageCount;
  if (pageCount2 > 1000) {
    pageCount2 = 1000;
  }
  let haba = 2;
  let startpage = page - haba;
  if (startpage < 2) {
    startpage = 2;
  }
  let endpage = page + haba;
  if (endpage >= pageCount2) {
    endpage = pageCount2 - 1;
  }
 
  const items = [];
  let k = -1;

  if (page > 2) {
    k++;
    items.push(
      <button
        key={k}
        className={styles.prevPageButton}
        onClick={() => pageDecrement()}
      >
        前へ
      </button>
    );
  }

  if (pageCount2 > 1) {
    k++;
    items.push(
      <button
        key={k}
        className={page == 1 ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(1)}
      >
        1
      </button>
    );
  }

  if (startpage >= 3) {
    k++;
    items.push(
      <span key={k} className={styles.pageSpan}>
        ...
      </span>
    );
  }

  for (let i = startpage; i <= endpage; i++) {
    k++;
    items.push(
      <button
        key={k}
        className={i == page ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(i)}
      >
        {i}
      </button>
    );
  }

  if (endpage <= pageCount2 - 2) {
    k++;
    items.push(
      <span key={k} className={styles.pageSpan}>
        ...
      </span>
    );
  }

  if (pageCount2 > 1) {
    k++;
    items.push(
      <button
        key={k}
        className={page == pageCount2 ? styles.pageButtonC : styles.pageButton}
        onClick={() => pageChange(pageCount2)}
      >
        {pageCount2}
      </button>
    );
  }

  if (page < pageCount2) {
    k++;
    items.push(
      <button
        key={k}
        className={styles.nextPageButton}
        onClick={() => pageIncrement()}
      >
        次へ
      </button>
    );
  }

  console.log("items ", items);

  return (
    <>
      <div>{items}</div>
      <div className={styles.pagination2}>
        {pageCount2 > 0 && `${page} / ${pageCount2} ページ`}
      </div>
    </>
  );
};

export default Paging;
0

1Answer

itemsにJSXオブジェクトを突っ込むよりかは...各要素をobjectとしてのデータで持ってそれをrender時にmapして、JSXオブジェクトを作るほうが良い気がしますが...

後、前、次、最初のページ、最後のページは固定で考えて、中間部分を回すようにしたら良い気がします。

1Like

Comments

  1. @ike81818

    Questioner

    ご回答ありがとうございます。
    ご教示いただきました方法につきまして、どのように具体的に記述するのか私の能力ではわからなかったため、上記のとおり、突貫工事的に修正しました。
    今後のことも考え、mapを使う方法についても勉強してみます。

Your answer might help someone💌