Mel*_*Mel 5 reactjs graphql prisma prisma-graphql
我正在尝试弄清楚如何访问我在应用程序中所做的更新突变中的 object.id 。
我有一个名为 IssueGroup 的对象。我已经创建和删除了突变,并且在大多数情况下,它们工作正常。我陷入了更新突变的困境,因为我似乎无法让它识别我正在尝试更新的对象的 id。
我有一个表格:
import * as React from "react"
import { gql } from "@apollo/client"
import type { IssueGroupInput } from "lib/graphql"
import { QueryMode, Role, SortOrder, useAllIssueGroupsQuery, useDeleteIssueGroupMutation, useUpdateIssueGroupMutation } from "lib/graphql"
import { AdminCreateIssueGroupForm } from "components/AdminCreateIssueGroupForm"
import { AdminUpdateIssueGroupForm } from "components/AdminUpdateIssueGroupForm"
import { Modal } from "components/Modal"
const __ = gql`
query AllIssueGroups {
allIssueGroups {
id
title
description
}
}
mutation deleteIssueGroup($id: String!) {
deleteIssueGroup(id: $id) {
id
title
description
issues
}
}
`
export default function IssueGroups() {
const [selectedIssueGroups, setSelectedIssueGroups] = React.useState<string[]>([])
const modalProps = useDisclosure()
const modalPropsUpdate = useDisclosure()
const [deleteIssueGroup] = useDeleteIssueGroupMutation()
const [updateIssueGroup] = useUpdateIssueGroupMutation()
const { data: issueGroup, refetch: refetchAllIssueGroups } = useAllIssueGroupsQuery()
const { data, loading, refetch } = useAllIssueGroupsQuery()
const allIssueGroups = data?.allIssueGroups
const onDeleteIssueGroup = (id: string) => {
return (
deleteIssueGroup({ variables: { id } }).then(() => refetch())
)
}
return (
<Box>
<Wrap mb={4} spacing={2}>
<Button
onClick={modalProps.onOpen}
}}
>
Create issue group
</Button>
</Wrap>
<Modal {...modalProps} title="Create Issue Group">
<AdminCreateIssueGroupForm onClose={modalProps.onClose} />
</Modal>
<IconButton
onClick={modalPropsUpdate.onOpen}
/>
<Modal {...modalPropsUpdate} title="Update Issue Group">
<AdminUpdateIssueGroupForm onClose=
{modalPropsUpdate.onClose} />
</Modal>
<IconButton
onClick={() => onDeleteIssueGroup(issueGroup.id)}
/>
))}
)
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一个在单击更新按钮时打开的模式,其中包含:
import * as React from "react"
import { gql } from "@apollo/client"
import { useRouter } from "next/router"
import { useAllIssueGroupsQuery, useUpdateIssueGroupMutation, IssueGroupInput } from "lib/graphql"
import { useForm } from "lib/hooks/useForm"
import Yup from "lib/yup"
const _ = gql`
query AllIssueGroups {
allIssueGroups {
id
title
description
issues
}
}
mutation updateIssueGroup($id: String!, $data: IssueGroupInput!) {
updateIssueGroup(id: $id, data: $data) {
id
title
description
issues
}
}
`
interface Props {
onClose: () => void
}
const IssueGroupSchema = Yup.object().shape({
title: Yup.string().required(),
description: Yup.string().required(),
})
export function AdminUpdateIssueGroupForm(props: Props) {
const router = useRouter()
const [updateIssueGroup] = useUpdateIssueGroupMutation()
const { data: issueGroups, refetch: refetchAllIssueGroups } = useAllIssueGroupsQuery()
const form = useForm({ schema: IssueGroupSchema })
const handleSubmit = async(data:IssueGroupInput) => {
console.log("made it to the handle submit before success handler")
return await form.handler(() => updateIssueGroup({
variables: {
id: issueGroup.id,
// I get an error that says Cannot find name 'issueGroup'. Did you mean 'issueGroups'.
// I know that's because I'm using the AllIssueGroups query to find many,
// but I don't know how to write the query to find the specific one I
// want to edit when I press the edit button in the form above
data: { ...data }
} }), {
onSuccess: (res, toast) => {
console.log("made it to the form handler success")
toast({ description: "Issue group updated" })
form.reset()
props.onClose()
},
})
}
return (
<Form {...form} onSubmit={handleSubmit}>
<Stack>
<Input name="title" label="Title" />
{/* <Input name="description" label="Description" /> */}
{/* <Text mb='8px' fontWeight="medium" fontSize="sm" > Description</Text> */}
<Textarea name="description" label="Describe" rows={4}/>
<Button onClick={props.onClose}>Cancel</Button>
type="submit"
>
Create
</Form>
)
}
Run Code Online (Sandbox Code Playgroud)
我的 IssueGroup 解析器有:
@Mutation(() => IssueGroup)
async updateIssueGroup(
@Arg("id") id: string,
@Arg("data") data: IssueGroupInput
) {
return await this.issueGroupService.updateIssueGroup(id, data)
}
@Query(() => IssueGroup)
async issueGroup(@Arg("id") id: string) {
return await this.issueGroupService.getIssueGroup(id)
}
Run Code Online (Sandbox Code Playgroud)
IssueGroup 服务具有:
async updateIssueGroup(id: string, data: IssueGroupInput) {
const issueGroup = await prisma.issueGroup.findUnique({ where: { id } })
if (!issueGroup) {
throw new Error("Issue not found")
}
return await prisma.issueGroup.update({ where: { id }, data })
}
async getIssueGroup(id: string) {
return await prisma.issueGroup.findUnique({
where: {
id,
},
})
}
Run Code Online (Sandbox Code Playgroud)
如何告诉更新模态表单与单击打开模态的按钮相关的特定 issuesGroup.id 是什么?
prisma 架构具有:
model IssueGroup {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
title String
description String
issues Issue[]
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}
model Issue {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
title String
description String
issueGroup IssueGroup? @relation(fields: [issueGroupId], references: [id], onDelete: SetNull, onUpdate: Cascade)
issueGroupId String? @db.Uuid
subscribers UserIssue[]
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}
Run Code Online (Sandbox Code Playgroud)
下一次尝试
我做了进一步的尝试,尝试使用 onClick 处理程序为模态提供 issuesGroup.id,但我仍然无法让表单识别 id,并且此版本的此尝试会生成一条错误消息,但我不这样做知道如何分解。它说:
输入 '{ onClose: () => void; 问题组:省略<问题组,“createdAt”| “更新时间” | “问题”> | 无效的; }' 不可分配给类型“IntrinsicAttributes & Props”。属性“issueGroup”不存在
关于类型“IntrinsicAttributes & Props”。
这次:
我尝试设置状态:
import { QueryMode, Role, SortOrder, useAllIssueGroupsQuery, useDeleteIssueGroupMutation, useUpdateIssueGroupMutation, IssueGroup as IssueGroupGQLType } from "lib/graphql"
const [selectedIssueGroup, setSelectedIssueGroup] = React.useState<Omit<
IssueGroupGQLType,
"createdAt" | "updatedAt" | "issues"
> | null>(null)
Run Code Online (Sandbox Code Playgroud)
更新按钮有:
<IconButton
aria-label='Update Issue Group'
// onClick={modalPropsUpdate.onOpen}
onClick={() => {
setSelectedIssueGroup(issueGroup)
modalPropsUpdate.onOpen()
<Modal {...modalPropsUpdate } title="Update Issue Group">
<AdminUpdateIssueGroupForm onClose={modalPropsUpdate.onClose} issueGroup ={selectedIssueGroup} />
</Modal>
Run Code Online (Sandbox Code Playgroud)
然后,在表单中,我尝试读取 issuesGroup.id:
const _ = gql`
query AllIssueGroups {
allIssueGroups {
id
title
description
issues
}
}
mutation updateIssueGroup($id: String!, $data: IssueGroupInput!) {
updateIssueGroup(id: $id, data: $data) {
id
title
description
issues
}
}
`
interface Props {
onClose: () => void
issueGroup: selectedIssueGroup
}
const IssueGroupSchema = Yup.object().shape({
title: Yup.string().required(),
description: Yup.string().required(),
})
export function AdminUpdateIssueGroupForm(props: Props) {
const router = useRouter()
const [updateIssueGroup] = useUpdateIssueGroupMutation()
// const { data: issueGroups, refetch: refetchAllIssueGroups } = useAllIssueGroupsQuery()
const form = useForm({ schema: IssueGroupSchema })
const handleSubmit = async( data:IssueGroupInput) => {
// await form.triggerValidation()
console.log("made it to the handle submit before success handler")
Run Code Online (Sandbox Code Playgroud)
下面的变量不知道issueGroup是什么
return await form.handler(() => updateIssueGroup({ variables: { id: issueGroup.id, data: { ...data } } }), {
onSuccess: (res, toast) => {
console.log("made it to the form handler success")
form.reset()
props.onClose()
},
})
}
return (
<Form {...form} onSubmit={handleSubmit}>
<Stack>
<Input name="title" label="Title" />
<Textarea name="description" label="Describe" rows={4}/>
<FormError />
<ButtonGroup>
<Button onClick={props.onClose}>Cancel</Button>
<Button
type="submit"
isLoading={form.formState.isSubmitting}
isDisabled={form.formState.isSubmitting}
>
Create
</Button>
</ButtonGroup>
</Stack>
</Form>
)
}
Run Code Online (Sandbox Code Playgroud)
经过这次尝试,我的表单仍然不知道 selectedIssueGroup 或 IssueGroup 的含义。
我已经看过react docs的这个页面,我认为我缺少的一点是我没有将我的表单包装在isActive的等效项中。问题是,我不知道将 selectedIssueGroup 放在哪里。我对该状态的定义位于与保存表单的文件不同的文件中。
为了尝试应用本文档中的逻辑,我尝试更改模式,以便将其包装在状态内,如下所示:
{selectedIssueGroup &&
<Modal {...modalPropsUpdate } title="Update Issue Group">
<AdminUpdateIssueGroupForm onClose={modalPropsUpdate.onClose} issueGroup ={selectedIssueGroup} />
</Modal>
}
Run Code Online (Sandbox Code Playgroud)
我没有收到任何新错误,但它也不起作用。我的表单仍然不知道问题组是什么。
我可以看到更新按钮知道问题组是什么,我可以看到模态也知道它。我不知道如何将该值赋予更新表单。
我已经看过本教程,它展示了如何使用创建表单进行编辑。它使用的屏幕截图显示了编辑表单中填充的创建信息,但没有显示它如何找到要在该表单中使用的数据。我找不到如何做到这一点的示例。
下一次尝试 12 月 21 日
在最近的尝试中,我尝试将 issuesGroup 引用添加为模态上的属性。即使这有效,我认为它也不会有帮助,原因如下所述。但是,我不明白为什么它不起作用。
<Modal {...modalPropsUpdate } issueGroup={selectedIssueGroup} title="Update Issue Group" >
Run Code Online (Sandbox Code Playgroud)
当我尝试此操作时,出现错误(VS 代码在上面的行中强调了 issuesGroup)。错误消息显示:
Run Code Online (Sandbox Code Playgroud)Type '{ children: (void | Element)[]; issueGroup: Omit<IssueGroup, "createdAt" | "updatedAt" | "issues"> | null; title: string; isOpen:布尔值;onOpen: () => void; ... 4 个以上 ...; getDisclosureProps: (props?: 任何) => 任何; }' 不可分配给类型 'IntrinsicAttributes & Props & {children?: ReactNode; }'。类型“IntrinsicAttributes & Props & {children?: ReactNode;”上不存在属性“issueGroup” }'。
我不知道这意味着什么。控制台登录在更新按钮内,模态上方和下方都知道issueGroup是什么。
我认为不需要的原因是我可以将问题组的值记录在模态上方以及加载表单的模态内的组件上方。两个日志都显示了我想在表单中使用的 issuesGroup 的值。
我正在尝试这样做:
const CheckIfModalKnowsIssueGroupId = props => {
console.log("checking if modal knows the issue group", props.toLog);
return (
<div>
{props.children}
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
ALTERNATE 尝试登录表单组件
<AdminUpdateIssueGroupForm
onClose={modalPropsUpdate.onClose}
issueGroup ={selectedIssueGroup}
>
<CheckIfModalKnowsIssueGroupId toLog={selectedIssueGroup} />
</AdminUpdateIssueGroupForm>
Run Code Online (Sandbox Code Playgroud)
下一次尝试 - 读取模态值
为了进一步尝试使模式承载 IssueGroup 的值,我尝试执行以下操作:
{selectedIssueGroup && modalPropsUpdate(isOpen:true) <Modal {...modalPropsUpdate } issueGroup={selectedIssueGroup} title="Update Issue Group" >
Run Code Online (Sandbox Code Playgroud)
这种尝试是错误的,因为我不知道如何使用 modalPropsUpdate。上述公式在 isOpen 测试中产生错误,如下所示:
const modalPropsUpdate: {
isOpen: boolean;
onOpen: () => void;
onClose: () => void;
onToggle: () => void;
isControlled: boolean;
getButtonProps: (props?: any) => any;
getDisclosureProps: (props?: any) => any;
}
Run Code Online (Sandbox Code Playgroud)
该表达式不可调用。类型 '{ isOpen: 布尔值; onOpen: () => void; onClose: () => void; onToggle: () => 无效; 受控:布尔值;getButtonProps: (props?: 任何) => 任何; getDisclosureProps: (props?: 任何) => 任何; }' 没有呼叫签名。
我找不到不会产生错误的语法。
此尝试的目的是查看模式是否打开,并且仍然知道 selectedIssueGroup 是什么。
新观察
我看过这个回购协议。我找不到使用我采用的结构来允许将 id 传递到表单的示例。
下一次尝试 12 月 23 日
我试图排除问题的根源,因为 selectedIssueGroup 状态处理程序被设置在与我试图用来更新对象的表单不同的组件中。因此,我将表单移至同一个文件中。它不起作用。udpate 表单处理程序仍然不知道 issuesGroup.id 或 selectedIssueGroup 的含义。
import * as React from "react"
import { gql } from "@apollo/client"
import { useRouter } from "next/router"
import type { IssueGroupInput } from "lib/graphql"
import { QueryMode, Role, SortOrder, useAllIssueGroupsQuery, useDeleteIssueGroupMutation, useUpdateIssueGroupMutation, IssueGroup as IssueGroupGQLType } from "lib/graphql"
// ,
import { AdminCreateIssueGroupForm } from "components/AdminCreateIssueGroupForm"
import Yup from "lib/yup"
const __ = gql`
query AllIssueGroups {
allIssueGroups {
id
title
description
}
}
mutation updateIssueGroup($id: String!, $data: IssueGroupInput!) {
updateIssueGroup(id: $id, data: $data) {
id
title
description
issues
}
}
`
const CheckIfModalKnowsIssueGroupId = props => {
console.log("checking if modal knows the issue group", props.toLog);
return (
<div>
{props.children}
</div>
);
};
const IssueGroupSchema = Yup.object().shape({
title: Yup.string().required(),
description: Yup.string().required(),
})
const form = useForm({ schema: IssueGroupSchema })
export default function IssueGroups() {
const [selectedIssueGroups, setSelectedIssueGroups] = React.useState<string[]>([])
const modalProps = useDisclosure()
const modalPropsUpdate = useDisclosure()
const [deleteIssueGroup] = useDeleteIssueGroupMutation()
const { data: issueGroup, refetch: refetchAllIssueGroups } = useAllIssueGroupsQuery()
const [selectedIssueGroup, setSelectedIssueGroup] = React.useState<Omit<
IssueGroupGQLType,
"createdAt" | "updatedAt" | "issues"
> | null>(null)
interface Props {
onClose: () => void
issueGroup: typeof selectedIssueGroup
}
function AdminUpdateIssueGroupForm(props: Props) {
const router = useRouter()
const [updateIssueGroup] = useUpdateIssueGroupMutation()
const handleSubmitUpdate = async( data:IssueGroupInput) => {
// await form.triggerValidation()
console.log("made it to the handle submit before success handler")
return await form.handler(() => updateIssueGroup({ variables: { id: issueGroup.id, data: { ...data } } }), {
onSuccess: (res, toast) => {
console.log("made it to the form handler success")
toast({ description: "Issue group updated" })
form.reset()
props.onClose()
},
})
}
const { data, loading, refetch } = useAllIssueGroupsQuery(
)
const allIssueGroups = data?.allIssueGroups
const onDeleteIssueGroup = (id: string) => {
return (
deleteIssueGroup({ variables: { id } }).then(() => refetch())
)
}
return (
<Wrap mb={4} spacing={2}>
<Button
onClick={modalProps.onOpen}
>
Create issue group
</Button>
</Wrap>
<Modal {...modalProps} title="Create Issue Group">
<AdminCreateIssueGroupForm onClose={modalProps.onClose} />
</Modal>
{data?.allIssueGroups.map((issueGroup) => (
<Tr key={issueGroup.id}>
<Text textStyle="h6">{issueGroup.title}</Text>
<IconButton
onClick={() => {
setSelectedIssueGroup(issueGroup)
modalPropsUpdate.onOpen()
}}
/>
{ console.log("update knows what the issuegroup is", selectedIssueGroup)}
<Modal {...modalPropsUpdate } title="Update Issue Group" >
<Form {...form} onSubmit={handleSubmitUpdate} >
<Stack>
<Input name="title" label="Title" />
<ButtonGroup>
<Button onClick={props.onClose}>Cancel</Button>
<Button
type="submit"
>
Save changes
</Button>
</ButtonGroup>
</Stack>
</Form>
</Modal>
<IconButton
onClick={() => onDeleteIssueGroup(issueGroup.id)}
/>
</ButtonGroup>
Run Code Online (Sandbox Code Playgroud)
从您发布的代码来看AdminUpdateIssueGroupForm,没有定义issueGroup如下的变量:
export function AdminUpdateIssueGroupForm(props: Props) {
const router = useRouter()
const [updateIssueGroup] = useUpdateIssueGroupMutation()
const { data: issueGroups, refetch: refetchAllIssueGroups } = useAllIssueGroupsQuery()
const form = useForm({ schema: IssueGroupSchema })
const handleSubmit = async(data:IssueGroupInput) => {
// await form.triggerValidation()
console.log("made it to the handle submit before success handler")
return await form.handler(() => updateIssueGroup({
variables: {
// ========== issueGroup has not yet been defined ===========
// ========== Do you need to pull anything out of the 'data' variable to get the right issueGroup variable? ===========
id: issueGroup.id,
Run Code Online (Sandbox Code Playgroud)
如果您希望更新从变量issueGroup派生的单个实例的数据issueGroups,它看起来像是从data您在handleSubmit函数中定义的变量派生的。