我想创建一个允许我从嵌套字段创建值的表单。相同突变中的根值可以正常工作,但是当我想创建嵌套值时,我不能。以下面的突变为例。
export const createPremise = (newPremiseEntry) => {
const mutation = gql`
mutation CreatePremise($input: PremiseInput!) {
createPremise(data: $input) {
_id
_ts
content
createdAt
}
}
`
return graphQLClient.request(mutation, { input: newPremiseEntry })
}
在 GraphQL Playground 中,我可以像这样创建嵌套操作
mutation{
createPremise(data:{
content: " This is a premise"
createdAt: "2020-09-23T17:01:00Z"
belongs:{
connect: "317324044732990025" //This is the _Id of the story it belongs too
}
})
{
// This is the return
_id
content
belongs {
name // This is the name of the Story, connected by the _id above.
}
}
}
现在,我可以在我的表单上创建一个没有嵌套值premise
的根值,如下所示:content
const ENTRIES_PATH = '/api/entries/allPremises'
const putPremiseEntry = (payload) =>
fetch(ENTRIES_PATH, {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json',
},
}).then((res) => (res.ok ? res.json() : Promise.reject(res)))
然后我这样做:
const useEntriesFlow = () => {
const onSubmit = async (payload) => {
await putPremiseEntry(payload)
await mutate(ENTRIES_PATH)
}
return {
onSubmit,
}
}
const EntryPremiseForm = ({ onSubmit: onSubmitProp }, storyId) => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const initial = {
content: '', // setting the initial state of content.
}
const [values, setValues] = useState(initial)
const [formState, setFormState] = useState('initial')
const isSubmitting = formState === 'submitting'
const onSubmit = (ev) => {
ev.preventDefault()
setFormState('submitting')
onSubmitProp(values)
.then(() => {
setValues(initial)
setFormState('submitted')
})
.catch(() => {
setFormState('failed')
})
}
const makeOnChange =
(fieldName) =>
({ target: { value } }) =>
setValues({
...values,
[fieldName]: value,
})
return (
<>
<form className="" onSubmit={onSubmit}>
//this is my input for creating the premise with content
<input required
className={cn(inputClasses, '')}
aria-label="premise"
placeholder="Premise"
value={values.content}
onChange={makeOnChange('content')} // On my form, I add the `content` value which goes into my premise object, creating the premise.
/>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? <LoadingSpinner /> : 'Create Premise'}
</Button>
</form>
{{
failed: () => <ErrorMessage>Something went wrong. :(</ErrorMessage>,
submitted: () => ( <SuccessMessage>Thanks for signing the guestbook.</SuccessMessage>
),
}[formState]?.()}
</>
)
}
这一切都很好,它的工作原理。
问题
当我需要做同样的事情,但有一个嵌套的额外字段时,问题就来了。这type Premise
属于另一个名为Story
type Story {
name: String!
createdAt: Time!
premises: [Premise] @relation
}
type Premise {
content: String!
belongs: Story!
createdAt: Time!
}
belongs
动物群是如何创建关系的
突变看起来像这样:
export const createPremise = (newPremiseEntry) => {
const mutation = gql`
mutation CreatePremise($input: PremiseInput!) {
createPremise(data: $input) {
_id
_ts
content
belongs{name} //nested relationship, not sure if syntax is correct.
createdAt
}
}
`
return graphQLClient.request(mutation, { input: newPremiseEntry })
}
区别在于:
belongs{name}
name
是它所属的故事的名称。上发现type Story
第一个问题
我如何在我的POST
?
export default async function handler(req, res) {
const handlers = {
POST: async () => {
const {
body: {
content,
belongs{name} // ?? WHAT DO I PUT HERE? HOW DO I REPRESENT BELONGS.NAME AS SEEN IN TYPE PREMISE?
},
} = req
const createdPremise = await createPremise({
content, belongs{name}, //???
createdAt: new Date(),
})
res.json(createdPremise)
},
}
if (!handlers[req.method]) {
return res.status(405).end()
}
await handlers[req.method]()
}
第二个问题
在我的const EntryPremiseForm
上面我如何表示belongs.name
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const initial = {
content: '',
belongs.name: '', //??? How do I set the inital state for this nested relationship field. remember, content works fine
}
当我拥有它时,我就可以做到这一点
<input
required
className={cn(inputClasses, '')}
aria-label="premise"
placeholder="Premise"
value={values.belongs.name} // ??? HOW DO I REPRESENT THAT HERE
onChange={makeOnChange('values.belongs.name')} //???
/>
非常感谢任何帮助。