reactjs - 来自 Graphql 的数组数据未填充 React 中的组件
问题描述
我正在尝试呈现具有两个功能的多个复选框:
- 显示两种状态:选中和未选中
- 使用选中的复选框更新选中的数组
目前,我可以使用虚拟数据成功实现这两个目标:
const dummyPlayers = [
{ id: 1, name: 'Puppa' },
{ id: 2, name: 'Korvo' },
{ id: 3, name: 'Jesse' },
{ id: 4, name: 'Terry' },
{ id: 5, name: 'Gobblins' }
]
这是我要填充复选框的数组的形状:
[
{
"id": "936d6050-00df-4bd4-bc54-6ce58ad0210c",
"name": "Travis",
"owner": "moralesfam",
"type": "Member",
"createdAt": "2021-09-24T20:08:02.292Z",
"updatedAt": "2021-09-24T20:08:02.292Z"
}...
]
但是,当我开始使用 Graphql 从数据库中提取数据时,虽然我能够将复选框呈现到 DOM,但它们不是交互式的(不显示选中状态)并且不记录选中的复选框。
我通过一个名为 useMembers 的自定义 React 钩子引入数据,一个对象数组,数据存储在成员数组中。控制台记录 members 打印出数组,但是一旦我将 dummyPlayers 交换为 members 数组,我之前所说的两个目标都不成功。
// RecordGame.js
import React, { useState } from 'react'
import useLoadMembers from '../hooks/useLoadMembers'
import useUser from '../hooks/useUser'
function RecordGame() {
const dummyPlayers = [
{ id: 1, name: 'Puppa' },
{ id: 2, name: 'Korvo' },
{ id: 3, name: 'Jesse' },
{ id: 4, name: 'Terry' },
{ id: 5, name: 'Gobblins' },
]
const { members } = useLoadMembers(updateLoading)
const { user } = useUser()
const [checkedState, setCheckedState] = useState(
new Array(members.length).fill(false)
)
let playingPlayers = []
for (var index in checkedState) {
if (checkedState[index] === true) {
playingPlayers.push(dummyPlayers[index])
}
}
console.log(playingPlayers)
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((player, index) =>
index === position ? !player : player
)
setCheckedState(updatedCheckedState)
}
// Rendered elements
const playerCheckboxes = dummyPlayers.map((player, index) => {
return (
<div key={index}>
<label htmlFor={player.name}>
<input
type="checkbox"
id={player.name}
name={player.name}
checked={checkedState[index]}
onChange={() => handleOnChange(index)}
/>
<span> {player.name}</span>
</label>
</div>
)
})
return (
<div>
<form>
{/* Game Players */}
<div>
<label htmlFor="players">
Who Played?
</label>
<div>{playerCheckboxes}</div>
</div>
</form>
</div>
)}
</Dashboard>
)
}
export default RecordGame
//useLoadMember.js
import { useState, useEffect } from 'react'
import { API, Auth } from 'aws-amplify'
import { listMembers } from '../graphql/queries'
const useLoadMembers = (updateLoading) => {
const [members, updateMembers] = useState([])
useEffect(() => {
fetchMembers()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const fetchMembers = async () => {
try {
let memberData = await API.graphql({
query: listMembers,
variables: { limit: 100 },
})
updateLoading(false)
let allMembers = memberData.data.listMembers.items
setFilteredMembers(allMembers)
} catch (err) {
console.error(err)
}
}
const setFilteredMembers = async (allMembers) => {
const { username } = await Auth.currentAuthenticatedUser()
const myMemberData = allMembers.filter((p) => p.owner === username)
updateMembers(myMemberData)
}
return { members }
}
export default useLoadMembers
在这第一张图片中,我使用了 dummyPlayers 数组并得到了我想要的结果。
但是,在第二个屏幕截图中,我将 dummyData 替换为 members 数组,但没有得到任何我想要的结果。
我只是对为什么使用相同的数组形状得到不同的结果感到困惑。
解决方案
无论您在哪里使用members
,都需要在使用之前检查成员是否未定义。如果 api 调用未完成,它将最初设置为未定义。
例如:members && members.map(() => ....)
推荐阅读
- html - 如何在 jquery-ui.css 中设置默认日期选择器箭头?
- javascript - 单击按钮显示不同的组件(反应组件类)
- javascript - VS Code 在使用 Live Server 时显示目录结构而不是 app.js 文件
- ruby - 在冰糕中,你能指定一个类型是一个类的后代吗?
- python - 如何将日志文件转换为 pandas DF
- linux - 内核模块重新加载后中断处理程序停止工作(Xilinx FPGA / PCIe)
- java - 哪个 java 类在 catalina.out 上发出警告
- java - 在反向代理后面访问 ElasticDB
- java - 避免对未获取的惰性对象进行 GSON 序列化
- python - 使用深度 CNN 和完全连接的分类器转换分割掩码 numpy 数组以进行图像分割