React: кнопка загрузки стилизованных компонентов

Я использую React-typescript для своего приложения. Для стилизации я использую Styled-components. Я создал один компонент глобальной кнопки. Внутри компонента кнопки я использовал загрузчик. Моя цель - когда пользователь нажмет кнопку, которая отобразит загрузку. Из родительского компонента я создал один поддельный вызов api и добавил туда settime-out 5s. Но когда я нажимаю кнопку, он не отображает загрузчик, который был в компоненте 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 и import 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>

person Krisna    schedule 30.06.2020    source источник


Ответы (1)


Вы должны создать состояние loading с помощью ловушки useState, если ваш родительский компонент - function component, если вы используете class component, вы можете определить состояние в конструкторе, как этот this.state = { loading: false }, в родительском компоненте, и установить его на true в handleClick и передать состояние в качестве опоры вашему 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>
person Trung Nguyen    schedule 30.06.2020
comment
Большое спасибо, дружище. Загрузка работает, но не отключает кнопку. - person Krisna; 30.06.2020
comment
Это то же самое, что и состояние loading, создайте состояние для disable. - person Trung Nguyen; 30.06.2020