質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

714閲覧

Lravelで作成したAPIをReactで呼んで更新処理を行いたいです。

tamago_3377

総合スコア1

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2023/03/02 01:07

編集2023/03/03 01:00

実現したいこと

  • 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}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

■エラーについて
TaskItemの部分がQueryClientProviderの外部でレンダリングされた場合、QueryClientProviderのコンテキストがないというエラーが出ているのかと思います。

■対応について
TaskItemコンポーネントでuseQueryClientを使用する場合、TaskListコンポーネント内にQueryClientProviderを追加することで、TaskItem内でuseQueryClientが正常に使用できるかと思います。

ソースだと下記のようになるかとおもいます

js

1import { TaskList } from '../components/tasks/TaskList'; 2import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; 3 4const queryClient = new QueryClient(); 5 6export const TaskPage = () => { 7 return ( 8 <QueryClientProvider client={queryClient}> 9 <TaskList /> 10 </QueryClientProvider> 11 ); 12};

投稿2023/03/03 01:03

pikimaru

総合スコア78

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamago_3377

2023/03/03 03:21

ありがとうございます。試したところ解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問