如何在React辅助函数中访问Context API暴露的方法?
场景最佳实践方案
方案1:API层完全解耦,Token作为参数传入(最推荐)
你抽离的数据库查询逻辑本质是通用数据请求层,不应该和React的Context绑定,去掉对useContext的依赖,将token改为入参即可。
改造后的辅助函数代码:
import axios from "axios"; import { mongoQuery } from "../xhr/QueryMongo"; export async function fetchUserData(userId, token) { const sRealmApp = "..."; const CancelTokenLogin = axios.CancelToken; const sourceLogin = CancelTokenLogin.source(); const userQuery = `query {user (query:{_id:"${userId}"}) {name, role, residence }}`; let queryResult = await mongoQuery(token, sRealmApp, userQuery, sourceLogin); if (queryResult.data.data !== null && queryResult.data.data.user !== null) { return queryResult.data.data.user; } else return false; }
在组件中调用时,使用useContext拿到token再传入即可:
import { useContext } from "react"; import { AuthContext } from "../../contexts/auth-context.js"; import { fetchUserData } from "你的辅助函数路径"; // 组件内部使用 function DemoComponent() { const { getAccessToken } = useContext(AuthContext); const handleGetUser = async (userId) => { const token = await getAccessToken("users"); const user = await fetchUserData(userId, token); // 后续业务逻辑 } }
这个方案的优势是请求层完全脱离React生态,可单独测试、复用,后续更换状态管理方案也不需要修改请求逻辑。
方案2:封装为自定义Hook
如果不想每次调用都手动传token,可以把请求逻辑封装为自定义Hook,Hook内部允许调用useContext,不会产生多余组件:
import React, { useContext } from "react"; import axios from "axios"; import { AuthContext } from "../../contexts/auth-context.js"; import { mongoQuery } from "../xhr/QueryMongo"; export function useUserApi() { const { getAccessToken } = useContext(AuthContext); const fetchUserData = async (userId) => { const sRealmApp = "..."; const CancelTokenLogin = axios.CancelToken; const sourceLogin = CancelTokenLogin.source(); let token = await getAccessToken("users"); const userQuery = `query {user (query:{_id:"${userId}"}) {name, role, residence }}`; let queryResult = await mongoQuery(token, sRealmApp, userQuery, sourceLogin); if (queryResult.data.data !== null && queryResult.data.data.user !== null) { return queryResult.data.data.user; } else return false; } return { fetchUserData } }
组件中使用方式:
import { useUserApi } from "你的辅助函数路径"; function DemoComponent() { const { fetchUserData } = useUserApi(); const handleGetUser = async (userId) => { const user = await fetchUserData(userId); // 后续业务逻辑 } }
方案3:从持久化存储直接读取Token(备选)
如果你的AuthContext的token本身是同步存储在localStorage/sessionStorage等全局可访问的存储中,也可以直接在辅助函数中读取存储中的token,不需要依赖Context:
import axios from "axios"; import { mongoQuery } from "../xhr/QueryMongo"; // 假设token存在localStorage,key为access_token export async function fetchUserData(userId) { const sRealmApp = "..."; const CancelTokenLogin = axios.CancelToken; const sourceLogin = CancelTokenLogin.source(); let token = localStorage.getItem('access_token'); const userQuery = `query {user (query:{_id:"${userId}"}) {name, role, residence }}`; let queryResult = await mongoQuery(token, sRealmApp, userQuery, sourceLogin); if (queryResult.data.data !== null && queryResult.data.data.user !== null) { return queryResult.data.data.user; } else return false; }
注意这个方案需要保证Context更新token时同步更新存储,避免出现token不一致的问题。
内容的提问来源于stack exchange,提问作者spaceBar
相关产品推荐
相关产品推荐

