React Query中fetch方法调用类内其他方法失败问题
问题:useQuery调用类实例方法时查询失败
我将数据获取逻辑抽象为独立的服务类TodoService,该类的fetchTodos方法会调用私有方法secretFetch获取数据。但把todoService.fetchTodos作为useQuery的参数使用时,查询出现失败。
相关代码如下:
TodoService 代码
import type { Todo } from './Todo'; class TodoService { private async secretFetch() { const todos = await fetch('https://jsonplaceholder.typicode.com/todos/'); return (await todos.json()) as Todo[]; } async fetchTodos() { const todos = await this.secretFetch(); return todos; } } const todoService = new TodoService(); export default todoService;
App 组件代码
export default function App() { const { data: todos, isLoading } = useQuery('todos', todoService.fetchTodos); if (isLoading) { return <p> Loading </p>; } if (todos.length === 0) { return <p> There are no todos </p>; } return ( <ul> {todos.map((todo) => ( <li> {todo.title} </li> ))} </ul> ); }
问题原因
核心问题是函数的this指向丢失。当你把todoService.fetchTodos作为单独的函数传递给useQuery时,这个函数脱离了原有的类实例上下文,调用时this不再指向todoService实例,导致this.secretFetch()调用失败(严格模式下this为undefined)。
解决方案
方案1:使用bind绑定上下文
在传递给useQuery时,通过bind把this绑定到todoService实例:
export default function App() { const { data: todos, isLoading } = useQuery('todos', todoService.fetchTodos.bind(todoService)); // 后续代码不变 }
方案2:用箭头函数包裹
通过箭头函数包裹方法调用,确保this始终指向类实例:
export default function App() { const { data: todos, isLoading } = useQuery('todos', () => todoService.fetchTodos()); // 后续代码不变 }
方案3:类内用箭头函数定义方法
直接在类中把fetchTodos定义为箭头函数,这样this会永久绑定到类实例:
class TodoService { private async secretFetch() { const todos = await fetch('https://jsonplaceholder.typicode.com/todos/'); return (await todos.json()) as Todo[]; } // 改为箭头函数 fetchTodos = async () => { const todos = await this.secretFetch(); return todos; } }
这种方式不需要修改组件代码,直接传递todoService.fetchTodos即可正常工作。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

