首页 > 解决方案 > 包含在链接中的自定义 HTML 按钮不起作用

问题描述

我制作了一个Button返回 HTML 的自定义组件button。现在我在Button里面Link使用这个next-routes。问题是它不能以这种方式工作。奇怪的是,如果我button在里面使用 HTML,按钮可以正常工作Link。但是,两个按钮都以完全相同的方式在 DOM 中呈现。以下是代码:

// Button.js

import React from "react";
import classNames from "classnames";

const Button = ({
    children,
    newClass = "",
    onClickHandler = () => { },
    isSubmitting = false,
    inlineBtn = true,
    disabled,
    primary,
    secondary,
    basic,
    notCentered = true,
    shaded,
    miniLoader,
    type = "button",
    isTransparent,
    fontClass = "",
    small
}) => {
    return (
        <React.Fragment>
            <button
                className={classNames(
                    `${isTransparent ? 'btn-transparent' : 'btn'} ${fontClass} ${newClass}`,
                    {
                        "btn-block": !inlineBtn,
                        "col-mx-auto": !notCentered,
                        "btn-primary": primary,
                        "btn-secondary": secondary,
                        "btn-basic": basic,
                        shaded: shaded,
                        loading: isSubmitting,
                        "loading-sm": miniLoader,
                        "btn-sm": small
                    }
                )}
                disabled={disabled}
                type={type}
                onClick={onClickHandler}
            >
                <span>{children}</span>
            </button>
        </React.Fragment>
    );
};

export { Button };

以下不起作用:

<Link route="/register/location">
  <Button basic small>
    Sign Up
  </Button>
</Link>

以下工作正常:

<Link route="/register/location">
  <button className="btn btn-basic btn-sm" type="button" onClick={() => { }}>
    <span>Sign Up</span>
  </button>
</Link>

标签: reactjsbuttonreact-routernext.js

解决方案


Button您可以按如下方式更新您的组件。

const Button = ({
  as = "button",
  children,
  newClass = "",
  onClickHandler = () => {},
  isSubmitting = false,
  inlineBtn = true,
  disabled,
  primary,
  secondary,
  basic,
  notCentered = true,
  shaded,
  miniLoader,
  type = "button",
  isTransparent,
  fontClass = "",
  small,
  ...rest
}) => {
  const Wrapper = as;
  return (
    <Wrapper
      className={classNames(
        `${isTransparent ? "btn-transparent" : "btn"} ${fontClass} ${newClass}`,
        {
          "btn-block": !inlineBtn,
          "col-mx-auto": !notCentered,
          "btn-primary": primary,
          "btn-secondary": secondary,
          "btn-basic": basic,
          shaded: shaded,
          loading: isSubmitting,
          "loading-sm": miniLoader,
          "btn-sm": small
        }
      )}
      disabled={disabled}
      type={type}
      onClick={onClickHandler}
      {...rest}
    >
      <span>{children}</span>
    </Wrapper>
  );
};

这将允许自定义Wrapper用于您的Button组件。我们将每个继承的道具传递给您Wrapper,以便您的route道具将在您的Link组件中接收。

然后你可以像这样使用它

<Button basic small as={Link} route="/register/location">
  Sign Up
</Button>

这使用 ES6 扩展运算符语法。基本上,您将Button组件渲染asLink组件,并且任何继承的道具都将传递给Link组件,因此route道具将传递给Link组件。

这遵循类似于 Material-ui 的快速方法的 API 设计方法。这也将使您的组件更加灵活。


推荐阅读