来自 Graphql 的数组数据未填充 React 中的组件
Array data from Graphql is not populating a component in 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,但它们不是交互式的(不显示选中状态)并且不t 记录选中的复选框。
我通过一个名为 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
,您都需要在使用之前检查成员是否未定义。如果 api 调用未完成,它将最初设置为未定义。
例如:members && members.map(() => ....)
我正在尝试呈现具有两个功能的多个复选框:
- 显示两种状态:选中和未选中
- 用选中的复选框更新选中的数组
目前,我已经成功地用虚拟数据完成了这两个目标:
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,但它们不是交互式的(不显示选中状态)并且不t 记录选中的复选框。
我通过一个名为 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
,您都需要在使用之前检查成员是否未定义。如果 api 调用未完成,它将最初设置为未定义。
例如:members && members.map(() => ....)