警告:列表中的每个孩子在 React.js 中都应该有一个唯一的“key”道具

Posted

技术标签:

【中文标题】警告:列表中的每个孩子在 React.js 中都应该有一个唯一的“key”道具【英文标题】:Warning: Each child in a list should have a unique "key" prop in React.js 【发布时间】:2021-07-03 13:55:58 【问题描述】:

我已经尝试了所有可能的方法来解决这个问题。 我将firebase firestore 用于数据库。

这就是我的数据在 Firestore - IMAGE 中的样子 这就是我的files directory 的样子-IMAGE

所以,我从Firestore 获取数据并将该数据传递给CardUIVerify.jsCardUIBan.js

Order of data- Data.js->CardUIVerify.js,CardUIBan.js->Panel.js->App.js->index.js

firestore(filename-Data.js)获取数据的代码-

import React,  useState, useEffect, createContext  from "react";
import fire from "../Firebase";

export const DataContext = createContext();

export function DataProvider( children ) 
  const [showdata, setShowData] = useState([]);

  const fetchedItem = async () => 
    var usersRef = await fire.firestore().collection(`users`);
    var response = await usersRef
      .where("isVerified", "==", false)
      .where("certificate", "==", null);

    response.onSnapshot((querySnapshot) => 
      var data = [];
      querySnapshot.forEach((doc) => 
        data.push(...showdata, doc.data());
      );
      setShowData(data);
    );
  ;
  useEffect(() => 
    fetchedItem();
  , []);

  return (
    <div>
      <DataContext.Provider value=[showdata, setShowData, fetchedItem]>
        children
      </DataContext.Provider>
    </div>
  );

这是CardUIVerify.js的代码-

import React,  useState, useEffect, useContext  from "react";
import  Card, Button  from "react-bootstrap";
import "./CardUIVerify.css";
import  DataContext  from "../contexts/Data";

function UIVerify() 
  const [showdata, setShowData] = useContext(DataContext);

  function renderCard(card) 
    return (
      <div id="grid1">
        <Card id="card-shape1" key=card.uid>
          <Card.Img className="card-img1" variant="top" src=card.photoUrl />
          <Card.Body>
            <Card.Title id="title1">
              card.name,card.gender == "Male" ? <>????</> : <>????‍♀️</>
            </Card.Title>
            <Card.Text className="details1">card.about</Card.Text>
            <Button
              className="custom-button11"
              variant="primary"
              size="md"
              active
              block
            >
              View Certificate
            </Button>
            <Button className="custom-button21" variant="success" active block>
              Verify
            </Button>
            <Button className="custom-button31" variant="danger" active block>
              Cancel
            </Button>
          </Card.Body>
        </Card>
      </div>
    );
  

  return <div>showdata && showdata.map(renderCard)</div>;

export default UIVerify;

这是CardUIBan.js的代码-

import React,  useState, useEffect, useContext  from "react";
import  Card, Button  from "react-bootstrap";
import "./CardUIBan.css";
import  DataContext  from "../contexts/Data";

function UIBan() 
  const [showdata, setShowData] = useContext(DataContext);

  function renderCard(card) 
    return (
      <div id="grid2">
        <Card id="card-shape2" key=card.uid>
          <Card.Img className="card-img2" variant="top" src=card.photoUrl />
          <Card.Body>
            <Card.Title id="title2">
              card.name,card.gender == "Male" ? <>????</> : <>????‍♀️</>
            </Card.Title>
            <Card.Text className="details2">card.about</Card.Text>
            <Button
              className="custom-button12"
              variant="primary"
              size="md"
              active
              block
            >
              View Obligations
            </Button>
            <Button className="custom-button22" variant="danger" active block>
              Ban User
            </Button>
            <Button className="custom-button32" variant="success" active block>
              Unban User
            </Button>
            <Button className="custom-button42" variant="danger" active block>
              Cancel
            </Button>
          </Card.Body>
        </Card>
      </div>
    );
  

  return <div>showdata && showdata.map(renderCard)</div>;

export default UIBan;

这是Panel.js的代码-

import React,  useContext  from "react";
import fire from "../Firebase";
import "./Panel.css";
import UIVerify from "./CardUIVerify";
import  DataContext  from "../contexts/Data";
import UIBan from "./CardUIBan";

function Panel() 

  const [showdata, setShowData, fetchedItem] = useContext(DataContext);
    
  function search1(event) 
    if (event.key === "Enter") 
      fetchedItem();
    
  

  function search2(event) 
    if (event.key === "Enter") 
      fetchedItem();
    
  

  return (
    <div className="app-panel">
      <div className="header-div">
        <h1 id="header">Welcome Admin</h1>
        <button className="panel-button" onClick=() => fire.auth().signOut()>
          Sign out
        </button>
      </div>

      <div className="verification-div">
        <h2 className="v-header">Verification</h2>
        <input
          className="search-1"
          name="search"
          type="text"
          placeholder="Search.."
          autocomplete="off"
          onKeyPress=search1
        />
        <UIVerify />
      </div>

      <div className="banned-div">
        <h2 className="b-header">Suspend</h2>
        <input
          className="search-2"
          name="search"
          type="text"
          placeholder="Search.."
          autocomplete="off"
          onKeyPress=search2
        />
        <UIBan />
      </div>
    </div>
  );

export default Panel;

这是App.js的代码-

import React,  useState  from "react";
import Login from "./components/Login";
import  BrowserRouter as Router, Route, Switch  from "react-router-dom";
import Panel from "./components/Panel";
import PrivateRoute from "./PrivateRoute";
import  AuthProvider  from "./Auth";
import  DataProvider  from "./contexts/Data";

function App() 
  return (
    <div>
      <AuthProvider>
        <Router>
          <div>
            <Switch>
              <PrivateRoute exact path="/" component=Panel />
              <Route exact path="/login" component=Login />
            </Switch>
          </div>
        </Router>
      </AuthProvider>
    </div>
  );


export default App;

这是index.js的代码-

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
import  DataProvider  from "./contexts/Data";
import  AuthProvider  from "./Auth";

ReactDOM.render(
  <React.StrictMode>
    <AuthProvider>
      <DataProvider>
        <App />
      </DataProvider>
    </AuthProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

这就是我的错误的样子—— ERROR IMAGE

提前致谢!

【问题讨论】:

【参考方案1】:

每当你渲染一个组件数组时,React 都会抱怨需要 key 属性。

在您的情况下,它可能是 return &lt;div&gt;showdata &amp;&amp; showdata.map(renderCard)&lt;/div&gt;; 导致您出现问题的行。要修复它,只需将&lt;div id="grid2"&gt; 更改为&lt;div id="grid2" key=card.id&gt;,如果您没有 id 属性,请使用唯一标识该卡的任何内容。

【讨论】:

像宝石一样工作。非常感谢你!!

以上是关于警告:列表中的每个孩子在 React.js 中都应该有一个唯一的“key”道具的主要内容,如果未能解决你的问题,请参考以下文章

警告:列表中的每个孩子都应该有一个唯一的“关键”道具。反应.js

“警告:列表中的每个子项在 React (TypeScript) 中都应该有一个唯一的“键”道具”

如何修复警告:列表中的每个孩子都应该有一个唯一的“关键”道具

React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具

添加了关键道具 ||警告:列表中的每个孩子都应该有一个唯一的“关键”道具

警告 - 列表中的每个孩子都应该有一个唯一的“关键”道具