React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具
Posted
技术标签:
【中文标题】React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具【英文标题】:React - Warning: Each child in a list should have a unique "key" prop 【发布时间】:2020-03-01 05:12:44 【问题描述】:在这个简单的 React App 中,我不明白为什么会收到以下警告消息:
警告:列表中的每个孩子都应该有一个唯一的“key”属性。
在我看来,我把密钥放在了正确的位置,形式为 key=item.login.uuid
我怎样才能摆脱警告信息? 把钥匙放在哪里合适?
App.js
import UserList from './List'
const App = props =>
const [id, newID] = useState(null)
return (
<>
<UserList id=id setID=newID />
</>
)
export default App
List.js
const UserList = ( id, setID ) =>
const [resources, setResources] = useState([])
const fetchResource = async () =>
const response = await axios.get(
'https://api.randomuser.me'
)
setResources(response.data.results)
useEffect(() =>
fetchResource()
, [])
const renderItem = (item, newID) =>
return (
<>
newID ? (
// User view
<div key=item.login.uuid>
<div>
<h2>
item.name.first item.name.last
</h2>
<p>
item.phone
<br />
item.email
</p>
<button onClick=() => setID(null)>
Back to the list
</button>
</div>
</div>
) : (
// List view
<li key=item.login.uuid>
<div>
<h2>
item.name.first item.name.last
</h2>
<button onClick=() => setID(item.login.uuid)>
Details
</button>
</div>
</li>
)
</>
)
const user = resources.find(user => user.login.uuid === id)
if (user)
// User view
return <div>renderItem(user, true)</div>
else
// List view
return (
<ul>
resources.map(user => renderItem(user, false))
</ul>
)
export default UserList
【问题讨论】:
【参考方案1】:key
需要位于循环内的根级元素上。在您的情况下,这就是片段 (<>
)。
要做到这一点,您需要完整地写出来:
const renderItem = (item, newID) =>
return (
<Fragment key=item.login.uuid>
newID ? (
...
)
</Fragment>
);
(您可以将Fragment
添加到来自react
的其他导入)。
请注意,您的示例中实际上不需要该片段,您可以删除它并将key
s 保留在它们所在的位置,此后<div>
和<li>
将成为根元素:
const renderItem = (item, newId) =>
return newID ? (
<div key=item.login.uuid>
...
</div>
) : (
<li key=item.login.uuid>
...
</li>
)
【讨论】:
【参考方案2】:如果您创建 2 个单独的组件,一个用于用户视图,一个用于列表项,该怎么办。这样你只需要传递用户道具。另外,使用 JSX 并从那里传递 wht 键。
const UserList = ( id, setID ) =>
const [resources, setResources] = useState([])
const fetchResource = async () =>
const response = await axios.get(
'https://api.randomuser.me'
)
setResources(response.data.results)
useEffect(() =>
fetchResource()
, [])
const User = (user) => (
<div key=user.login.uuid>
<div>
<h2>
user.name.first user.name.last
</h2>
<p>
user.phone
<br />
user.email
</p>
<button onClick=() => setID(null)>
Back to the list
</button>
</div>
</div>
)
const ListItem = (user) => (
<li key=user.login.uuid>
<div>
<h2>
user.name.first user.name.last
</h2>
<button onClick=() => setID(user.login.uuid)>
Details
</button>
</div>
</li>
)
const user = resources.find(user => user.login.uuid === id)
if (user)
// User view
return <User user=user</div>
else
// List view
return (
<ul>
resources.map((user, index) => <ListItem key=index user=user />)
</ul>
)
export default UserList
【讨论】:
以上是关于React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具的主要内容,如果未能解决你的问题,请参考以下文章
警告:列表中的每个孩子在 React.js 中都应该有一个唯一的“key”道具
如何修复警告:列表中的每个孩子都应该有一个唯一的“关键”道具
警告:列表中的每个孩子都应该有一个唯一的“关键”道具。反应.js