The problem:我有一个具有多个按钮的父组件.每个按钮将从API获取不同端点的数据.要求是,当一个按钮被点击时,它应该进入加载状态,并且其他按钮应该被禁用,直到呼叫完成.

What I have tried:我创建了两个独立的按钮组件<Button1><Button2>,它们有自己的isLoading状态.我在父组件中声明了disabled状态,并将此状态及其set处理程序作为props 传递给子按钮组件.当命中onClick函数时,我将isLoading状态设置为True,并将setDisabled属性设置为True,以通知父组件.我已经将每个子按钮组件上的disabled属性的逻辑编写为diabled={!isLoading && disabled},这意味着如果按钮不是进行API调用/加载的按钮,则将被禁用.

为该方法的实现添加代码沙箱,并添加所需的沙箱:https://codesandbox.io/s/sharp-hill-r4rsk0?file=/src/App.js

Solution support required:我需要一种方法来减少代码重复,方法是多次使用单个<Button>组件而不是多个按钮组件作为父组件中的子级,但不知道当单击其中任何一个时如何分离它们的isLoadingdisabledonClick状态和处理程序,它的工作方式应该与上面沙箱中看到的方法1中的工作方式相同.

推荐答案

请判断我的代码是否符合您的要求.

import { useState } from "react";

const Button = ({ children, loading, disabled, onClick }) => {
  return (
    <button disabled={disabled} onClick={onClick}>
      {loading ? "Loading..." : children}
    </button>
  );
};

const ButtonWrapper = ({ url, onFetching, disabled, children }) => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState();

  const getData = () => {
    setLoading(true);
    onFetching(true);
    fetch(url)
      .then((response) => response.json())
      .then((json) => setData(json))
      .finally(() => {
        setLoading(false);
        onFetching(false);
      });
  };

  return (
    <Button loading={loading} disabled={disabled} onClick={() => getData()}>
      {children}
    </Button>
  );
};

export default function App() {
  const [isFetching, setIsFetching] = useState(false);

  return (
    <div className="App">
      <ButtonWrapper
        onFetching={setIsFetching}
        disabled={isFetching}
        url="https://jsonplaceholder.typicode.com/posts"
      >
        Fetch Posts
      </ButtonWrapper>

      <ButtonWrapper
        onFetching={setIsFetching}
        disabled={isFetching}
        url="https://jsonplaceholder.typicode.com/albums"
      >
        Fetch Albums
      </ButtonWrapper>

      <ButtonWrapper
        onFetching={setIsFetching}
        disabled={isFetching}
        url="https://jsonplaceholder.typicode.com/users"
      >
        Fetch Users
      </ButtonWrapper>
    </div>
  );
}

我已经在相同的文件中编码,但你可以制作一个单独的文件,也确保改变网络网络节流,以降低3G或其他什么,以清楚地看到功能.

演示:https://codesandbox.io/s/cranky-shannon-vtwmz8?file=/src/App.js

Reactjs相关问答推荐

使用Thattle和Use Effect setTimeout进行搜索有什么不同

StyleX中的多语言支持

TanStack/Reaction-Query在我的Vercel应用程序中不起作用

如何在物料界面react 的多选菜单中设置最大 Select 数限制

透明MOV文件未出现在我的React网页中

PWA:注册事件侦听器不会被触发

警告:遇到两个子元素拥有同一把 keys .键应该是唯一的,以便组件在更新时保持其身份

强制 useEffect 仅运行一次

Mui Datepicker 设置了错误的日期

React Router 6 点击链接在 React 18 应用中打开 flickr 页面

BrowserRouter改变了URL但没有链接到页面

在 Nextjs13 应用程序目录中呈现从 supabase 获取的数据

React v6 中的公共和私有路由

在准备回调中使用状态属性(Redux 工具包)

如何通过onpress on view in react native flatlist来降低和增加特定视图的高度?

如何将我的 ID 值传递给下一个组件?

导航到屏幕时,react 本机上下文状态变为未定义

如何制作基于对象 struct 呈现数据的可重用组件?

react 路由路由加载器不适用于嵌套组件

ClearInterval 在 React 中的 useRef 没有按预期工作