这里主要是介绍一下思路:使用HOC组合Provider,并且在HOC中向Provider中提供数据,组件在使用Context通过useXXX使用Provider的数据
如有不足,欢迎指导
架构层
UserInfoContext
子组件可以通过useUserInfo
钩子获取到数据
interface UserQueryInfo{
username:'xxx',
userId:'xxx',
}
const UserInfoContext = createContext<UserQueryInfo>(null)
export const UserInfoProvider = ({children,userQueryInfo}:{children,React.ReactNode,userQueryInfo:UserQueryInfo}) =>{
return <UserInfoContext.Provider value = {userQueryInfo}>
{children}
</UserInfoContext.Provider>
}
export const useUserInfo = ()=>{
return useContext(UserInfoContext)
}
AxiosContext
子组件可以使用useAxios
获取到封装的axios实例
const AxiosContext = createContext(null)
// 封装axios,为请求添加token信息
const createAxiosInstance = (sessionToken, router)) =>{
return axios.create({
...
})
}
export function AxiosProvider({ children }:{children:React.ReactNode}){
const sessionToken = session.getItem('token')
// 如果在这里想要获取用户信息,通过useUserInfo钩子获取用户信息
const [axiosInstance] = React.useState(() => createAxiosInstance(sessionToken, router));
return <AxiosContext.provider value = {axiosInstance} >
{children}
</AxiosContext.provider>
}
export const useAxios = () => {
// 获取axios实例
return useContext(AxiosContext)
}
withAuthApp
使用HOC的方式,结合两个Provider像下层提供数据
import { UserInfoProvider } from './UserInfoContext'
import { AxiosProvider } from './AxiosContext'
import { ErrorBounding } from './xxx'
import { Loading } from './xxx'
// withAuthApp
export const withAuthApp = (Component) =>{
const [ queryInfo ] = useState(() => getUserInfo())// 从某个地方获取用户数据
// 返回一个组件
return (props)=>{
<ErrorBounding>
<!-- 像全局提供queryInfo信息 -->
<UserInfoProvider queryInfo = {queryInfo}>
<AxiosProvider>
<Suspense fallback = {Loading}>
<Component {...props}/>
</Suspense>
</AxiosProvider>
</UserInfoProvider>
</ErrorBounding>
}
}
应用层
App.tsx
// ./App.tsx
import {useApis} from './api'
import { useQuery } from '@tanstack/react-query'
import {withAuthApp} from './withAuthApp'
const App = (props) => {
const { getXXXList } = useApis();
const userInfo = useUserInfo();
const { data,loading,refetch } = useQuery(['search'],()=>getXXXList(userInfo.id),{
onSuccess:()=>{},
onError:()=>{}
})
console.log(data)
<div>
<Home {...props}>
</div>
}
export default withAuthApp(App)
api.ts
// ./api.ts
import { useAxios } from './AxiosContext'
export function useApis(){
const axios = useAxios();
return {
getXXXList:(json)=> axios.get('./xxx/xxx',json);
}
}