首页 > 解决方案 > React:样式化组件加载按钮

问题描述

我正在为我的应用程序使用 React-typescript。对于样式,我正在使用Styled-components。我创建了一个全局按钮组件。在按钮组件内部,我使用了加载器。我的目标是当用户单击将显示加载的按钮时。我从父组件创建了一个虚假的 api 调用,并在其中添加了settime-out5s。但是当我单击按钮时,它不会显示 Button 组件中的加载程序。从父组件设置超时工作,它显示在我的控制台中。不知道为什么不显示loading ....。当假 api 调用按钮应该被禁用时,我还添加了禁用选项。这种逻辑也行不通。

这是按钮组件

import * as React from "react";
import styled, { css } from "styled-components";

interface IButtonProps {
  children?: React.ReactChild;
  className?: string;
  size?: "small" | "medium" | "big";
  themes?: "primary" | "secondary" | "dark" | "light";
  disabled?: boolean;
  loading?: boolean;
  style?: React.CSSProperties;
  onClick?: () => void;
  onSubmit?: () => void;
}

const Button = ({
  children,
  className,
  size,
  themes,
  disabled,
  loading,
  style,
  onClick,
  onSubmit
}: IButtonProps) => (
    <button
      className={className}
      onClick={onClick}
      onSubmit={onSubmit}
      style={
        disabled && disabled 
          ? { opacity: 0.5, pointerEvents: `none` }
          : loading ? { ...style, pointerEvents: `none` } : //This is my disabled condition.
            style
      }
    >
      {loading ? <p>loading...</p> : children} //This is my loading condition.
    </button>
  );

const sizes = {
  small: css`
    padding: 5px 20px;
    font-size: 12px;
  `,
  medium: css`
    padding: 10px 30px;
    font-size: 14px;
  `,
  big: css`
    padding: 15px 40px;
    font-size: 18px;
  `
};

const ButtonThemes = {
  primary: css`
    border: 1px solid tomato;
    background: tomato;
    color: white;
  `,
  secondary: css`
    border: 1px solid palevioletred;
    background: palevioletred;
    color: white;
  `,
  dark: css`
    border: 1px solid #273444;
    background: #273444;
    color: white;
  `,
  light: css`
    border: 1px solid #eff2f7;
    background: #f9fafc;
    color: #273444;
  `
};

const StyledButton = styled(Button)`
  ${({ size = "small" }) => sizes[size]};
  ${({ themes = "primary" }) => ButtonThemes[themes]};
  outline: none;
  border-radius: 5px;
  cursor: pointer;
`;

export default StyledButton;

这是我的父组件。我在哪里使用 settimeout 并导入 Button 组件。

const handleClick = () => { 
    setTimeout(() => {
      console.log("check it out") //It does display when the button click 
    }, 5000);
  }

   //This is the Button 
       <Button size="medium" themes="primary" onClick={handleClick}>click</Button>

标签: buttonstyled-componentsreact-typescript

解决方案


loading如果您的父组件是 ,您应该使用useState钩子创建一个状态function component,如果使用class component您可以在父组件中像这样在构造函数中定义一个状态this.state = { loading: false },并将其设置为trueinhandleClick并将状态作为 prop 传递给您的Button组件:

// In case function component
const [loading, setLoading] = useState(false);
const handleClick = () => {
    setLoading(true); 
    setTimeout(() => {
      setLoading(false); // When finish, set it to false
      console.log("check it out") //It does display when the button click 
    }, 5000);
}

//This is the Button 
<Button 
  size="medium" 
  themes="primary" 
  onClick={handleClick} 
  loading={loading}
>
   click
</Button>

推荐阅读