実現したいこと
- Reactでデータの更新処理を行いたい。
- laravelでAPIを作成したのでReactでAPIを呼び出し更新を行いたい
- 現状
const queryClient = useQueryClient();
を記載するとエラーが出るため解消したい
前提
- laravelとReactを使用したSPAアップリを作成しようとしています。
- 現状はAPIで一覧取得と更新処理を作成しています。
- 一覧取得API呼び出しで一覧表示についてはできています。
- 更新処理についてReact側で実装している際にエラーが発生してしまいました。
使用しているバージョン
- "@tanstack/react-query": "^4.24.10",
- "@types/react": "^18.0.28",
- "@types/react-dom": "^18.0.11",
- "@types/react-router-dom": "^5.3.3",
- "@vitejs/plugin-react": "^3.1.0",
- "axios": "^1.1.2",
発生している問題・エラーメッセージ
react-dom.development.js:86 Warning: React has detected a change in the order of Hooks called by TaskList. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks Previous render Next render ------------------------------------------------------ 1. useContext useContext 2. useContext useContext 3. useContext useContext 4. useContext useContext 5. useEffect useEffect 6. useState useState 7. useCallback useCallback 8. useSyncExternalStore useSyncExternalStore 9. useEffect useEffect 10. undefined useContext ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ at TaskList (http://[::1]:5173/resources/ts/pages/tasks/components/TaskList.tsx?t=1677688672593:24:7) at TaskPage at RenderedRoute (http://[::1]:5173/node_modules/.vite/deps/react-router-dom.js?v=e6c9ae10:2975:5) at Routes (http://[::1]:5173/node_modules/.vite/deps/react-router-dom.js?v=e6c9ae10:3320:5) at Router (http://[::1]:5173/node_modules/.vite/deps/react-router-dom.js?v=e6c9ae10:3267:15) at BrowserRouter (http://[::1]:5173/node_modules/.vite/deps/react-router-dom.js?v=e6c9ae10:3680:5) at Router at QueryClientProvider (http://[::1]:5173/node_modules/.vite/deps/@tanstack_react-query.js?v=e6c9ae10:2780:3) at App
Uncaught Error: Rendered more hooks than during the previous render. at updateWorkInProgressHook (react-dom.development.js:16507:13) at updateReducer (react-dom.development.js:16568:14) at updateState (react-dom.development.js:17004:10) at Object.useState (react-dom.development.js:17915:16) at Object.useState (react.development.js:1622:21) at useMutation (useMutation.ts:83:28) at useUpdateDoneTask (TaskQuery.tsx:13:12) at TaskItem (TaskItem.tsx:6:28) at TaskList.tsx:18:21 at Array.map (<anonymous>)
該当のソースコード
resources/ts/App.tsx
js
1import { Router } from './Router'; 2import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 3 4const queryClient = new QueryClient({ 5 defaultOptions: { 6 queries: { 7 retry: false 8 }, 9 mutations: { 10 retry: false 11 } 12 } 13}); 14 15export const App = () => { 16 return ( 17 <QueryClientProvider client={queryClient}> 18 <Router /> 19 </QueryClientProvider> 20 ) 21}
resources/ts/pages/tasks/index.tsx
js
1import { TaskInput } from './components/TaskInput'; 2import { TaskList } from './components/TaskList'; 3 4export const TaskPage = (): JSX.Element => { 5 return ( 6 <> 7 <TaskInput /> 8 <TaskList /> 9 </> 10 ); 11}
resources/ts/pages/tasks/components/TaskItem.tsx
js
1import { Task } from '../../../types/Task'; 2import { useUpdateDoneTask } from '../../../queries/TaskQuery'; 3 4 5export const TaskItem = (task: Task): JSX.Element => { 6 const updateDoneTask = useUpdateDoneTask(); 7 return ( 8 <li key={task.id} className={task.is_done ? 'done' : ''} > 9 <label className="checkbox-label"> 10 <input 11 type="checkbox" 12 className="checkbox-input" 13 onClick={() => updateDoneTask.mutate(task)} 14 /> 15 </label> 16 <div><span>{task.title}</span></div> 17 <button className="btn is-delete">削除</button> 18 </li> 19 ); 20}
resources/ts/queries/TaskQuery.tsx
js
1import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; 2import * as api from '../api/TaskAPI'; 3 4export const useTasks = () => { 5 return useQuery(['tasks'],async () => api.getTasks()) 6} 7 8export const useUpdateDoneTask = () => { 9 // 下記を記載するとエラーが発生 10 const queryClient = useQueryClient(); 11 12 return useMutation(api.updateDoneTask, { 13 onSuccess: () => { 14 queryClient.invalidateQueries(['tasks']); 15 } 16 }); 17}
resources/ts/api/TaskAPI.tsx
js
1import axios from 'axios'; 2import { Task } from '../types/Task'; 3 4export const getTasks = async () =>{ 5 const { data } = await axios.get<Task[]>('api/tasks') 6 return data 7} 8 9export const updateDoneTask = async ({ id, is_done }: Task) =>{ 10 const { data } = await axios.patch<Task[]>( 11 `/api/tasks/update-done/${id}`, 12 { is_done: !is_done } 13 ) 14 console.log(data) 15 return data 16}
routes/api.php
php
1 2<?php 3 4use Illuminate\Http\Request; 5use Illuminate\Support\Facades\Route; 6 7Route::apiResource('/tasks', 'App\Http\Controllers\TaskController'); 8Route::patch('tasks/update-done/{task}', 'App\Http\Controllers\TaskController@updateDone'); 9 10Route::middleware('auth:sanctum')->get('/user', function (Request $request) { 11 return $request->user(); 12});
app/Http/Controllers/TaskController.php
php
1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6use App\Http\Requests\TaskRequest; 7use App\Models\Task; 8 9class TaskController extends Controller 10{ 11 12~~~~略 13 /** 14 * is_doneの更新 15 * 16 * @param Task $task 17 * @param Request $request 18 * @return \Illuminate\Http\JsonResponse 19 */ 20 public function updateDone(task $task, Request $request) 21 { 22 $task->is_done = $request->is_done; 23 24 return $task->update() 25 ? response()->json($task) 26 : response()->json([], 500); 27 } 28}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/03/03 03:21