thanks for your reading. I'm trying to commit a relay mutation of using the useMutation hook, but got the error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
My CreateProjectMutation.js is
import { graphql, useMutation } from 'react-relay';
export default function CreateProjectMutation(content, leader, startDate, callback) {
console.log("fake CreateProjectMutation");
const [commit, isInFlight] = useMutation(graphql`
mutation CreateProjectMutation($input:createProjectInput!) {
createProject(input:$input) {
project {
id
content
leader
}
}
}
`)
const variables = {
input: {
content,
leader,
startDate,
}
}
commit({
variables,
onCompleted: () => {
callback();
},
}
)
}
And the app.js calling it is
import React, { useState } from 'react';
import CreateProjectMutation from '../mutations/CreateProjectMutation';
export default function CreateProject() {
const [leader, setLeader] = useState("");
const [content, setContent] = useState("");
const [date, setDate] = useState("");
const submitProject = () => {
CreateProjectMutation(content, leader, date, (data) => { console.log(data) });
clearForm();
}
const clearForm = () => {
setLeader("");
setContent("");
setDate("");
}
return (
<div>
<label>Leader</label>
<input
value={leader}
onChange={(event) => { setLeader(event.target.value) }} />
<label>content</label>
<input
value={content}
onChange={(event) => { setContent(event.target.value) }} />
<label>start date</label>
<input
value={date}
onChange={(event) => { setDate(event.target.value) }} />
<button onClick={submitProject}>Submit</button>
</div>
)
}
I tried several ways to solve the problem.
Using the old version hook API commitMutation, it's successful. But I cannot transfer it to the useMutation, and the doc here only says Todo... official doc link
Try to explore with the error message. I visit the linked file (https://reactjs.org/link/invalid-hook-call). 1)Mismatching Versions of React and React DOM -> not satisfied 2)Breaking the Rules of Hooks -> I think most likely this is the reason because I used hook inside the onclick. And when I turned the :
const submitProject = () => {
CreateProjectMutation(content, leader, date, (data) => { console.log(data) });
clearForm();
}
into
const submitProject = () => {
//CreateProjectMutation(content, leader, date, (data) => { console.log(data) });
clearForm();
}
It's successful.
I'm not very sure the problem is here. However, even though I may find the reason correct, I still didn't find any result telling me how to deal with this situation without putting the hook inside the onclick. Because What I hope to do is when the user clicks the submit button, the CreateProjectMutation API will be called to handle the request. I cannot see how can I avoid the problem.
Could someone please help me? Thanks so much!
The error message gave you the answer in the first sentence:
The docs confirm:
Your
CreateProjectMutation
is not a React component, and you cannot call a hook in the manner you've attempted.Call the hook from the top level of your component instead.