我很难理解reaction/redux/rtkQuery是如何使用的.我知道这可能是个愚蠢的问题.不幸的是,除了许多参考文献说这不能用这种方式做之外,我找不到一个建议如何才能达到预期的效果.下面显示了我想要做的事情的代码片段.

具体地说,我使用的是使用rtkQuery构建的API Slice.

  • 一个端点myUserProfile获取当前登录用户的用户配置文件.这本身就是有效的.
  • 另一端点userStub获得任何指定用户的编辑用户简档.如果我为组件提供了一个静态的user_id,这也是有效的.

我想要做的是创建一个呈现用户配置文件存根的组件.如果指定了user_id,则会显示该user_id的配置文件.如果不是,那么我希望使用myUserProfile来获取当前登录用户的user_id.

但是,不能保证在呈现该组件时缓存中存在myUserProfile结果.这意味着:

  • 如果没有指定user_id,那么我实际上不能调用userStub,因为我没有一个有效的参数来给它.
  • myUserProfile可能需要一些时间来检索用户配置文件.
  • 由于条件呈现,特别是对profileIsFetching的判断,我将在组件的不同执行中使用不同数量的钩子.这是不允许的.

如何实现有条件的API调用/API调用的排序才能达到这种效果?


import React from "react";
import { useMyUserProfileQuery, useUserStubQuery } from "../endpoints/user";


interface UserStubProps {
  user_id?: string;
}


const UserStub: React.FC<UserStubProps> = ({ user_id }) => {
  
  if (!user_id){
      const { data: profile, isFetching : profileIsFetching } = useMyUserProfileQuery();
      if (profileIsFetching){
        return (
          <div> Loading Profile ... </div>
        )
      }
      user_id = profile?.auth0.user_id!;
  }
  
  const { data, isFetching } = useUserStubQuery(user_id);    
  
  if (isFetching){
      return (
        <div>
          Loading ...
        </div>
      );
  }

  return (
      <div>
          <p> Name : {data?.name} </p>
          <p> Nickname : {data?.nickname} </p>
          <p> Picture : <img src={data?.picture.toString()}></img> </p>
          <p> User ID : {data?.user_id} </p>
      </div>
  )
}


export default UserStub;

编辑:

我try 创建自定义钩子,并按如下方式使用:

export const useCurrentUserId = () => {
    const { data, isLoading, isError } = useMyUserProfileQuery();
    const userId = data?.auth0?.user_id; 
    return { userId, isLoading, isError };
};

const UserStub: React.FC<UserStubProps> = ({ user_id }) => {
  const { userId, isLoading } = useCurrentUserId()
  
  if (!user_id) { user_id = userId; }
  
  // TODO this results in a bad request to the server with null 
  // user_id before the earlier hook completes. 
  const { data, isFetching } = useUserStubQuery(user_id!);    
  
  if (isFetching || isLoading){
      return ( <div> Loading ... </div>);
  }

  return (....)
}

然而,这几乎遇到了同样的问题.useUserStubQuery被空user_id调用,这会导致向API服务器发出错误的请求.

推荐答案

在这两个代码用例/示例中,您仍然有条件地调用Reaction钩子,这违反了React的钩子规则.

如果我正确理解了您的问题/问题,您希望在没有传递user_idprops 值时有条件地调用useMyUserProfileQuery钩子,在当前用户的user_id属性105有传递的user_idprops 值时有条件地调用useUserStubQuery.

import React from "react";
import { useMyUserProfileQuery, useUserStubQuery } from "../endpoints/user";

interface UserStubProps {
  user_id?: string;
}

const UserStub = ({ user_id }: UserStubProps) => {
  const {
    data: profile,
    isFetching: profileIsFetching,
  } = useMyUserProfileQuery(_, { skip: !user_id });

  const stubId = profile?.auth0?.user_id ?? user_id;
  const {
    data,
    isFetching,
  } = useUserStubQuery(stubId, { skip: !stubId });

  if (profileIsFetching) {
    return <div>Loading Profile ...</div>;
  }   
  
  if (isFetching) {
    return (
      <div>
        Loading ...
      </div>
    );
  }

  return (
    <div>
      <p>Name: {data?.name}</p>
      <p>Nickname: {data?.nickname}</p>
      <p>
        Picture: <img alt="profile src={data?.picture.toString()} />
      </p>
      <p>User ID: {data?.user_id}</p>
    </div>
  );
}

export default UserStub;

有关更多详细信息,请参见Conditional Fetching.

Reactjs相关问答推荐

客户端组件中服务器组件的两难境地

react 路由导航不工作,但手动路由工作

无法从正在使用Reaction的Electron 商务store 项目中的购物车中删除项目

页面永远加载API/从数据库获取数据

Reaction路由DOM v6不包含上下文(Supabase)

使用Next.js和Next-intl重写区域设置

强制 useEffect 仅运行一次

react :输入失go 焦点,输入一个字符,

标签文本删除了 MUI 概述的输入

组件安装后调用自定义钩子

如何更改TimePicker中下拉菜单的背景 colored颜色 和字体 colored颜色 - MUI React

从 redux 调用UPDATE_DATA操作时状态变得未定义

useState数组不更新

在 CrafterCMS Studio 中拖动字段

从 React 应用程序调用未经身份验证的 graphql 查询时出现错误:没有当前用户

文本的几个词具有线性渐变 colored颜色 - React native

从服务器获取数据时未定义,错误非法调用

谁能根据经验提供有关 useEffect 挂钩的更多信息

React Hooks 表单在日志(log)中显示未定义的用户名

Select MenuItem 时 Material-ui 不更改样式