如何创建一个React按钮(附代码示例)

1,296 阅读3分钟

一个按钮可能是你在React组件中使用的第一个交互式元素。因此,这是一个简短的React教程,通过实例向初学者介绍在React中创建一个按钮,如何使用它,以及如何将它提取为一个可重用的组件。首先,按钮只是一个HTML按钮元素,可以在React的JSX中呈现:

import * as React from 'react';

const App = () => {
  return (
    <div>
      <button type="button">Click Me</button>
    </div>
  );
};

export default App;

通过使用React中的事件处理程序,我们可以对按钮的点击事件做出反应:

import * as React from 'react';

const App = () => {
  const handleClick = () => {
    // implementation details
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        Click Me
      </button>
    </div>
  );
};

export default App;

这样,一个按钮就可以用来在点击它时触发各种效果。例如,通过使用React的useState Hook,它可以改变一个有状态的值:

import * as React from 'react';

const App = () => {
  const [count, setCount] = React.useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        Click Me
      </button>

      {count}
    </div>
  );
};

export default App;

另一个例子是切换一个条件渲染:

import * as React from 'react';

const App = () => {
  const [isOpen, setOpen] = React.useState(false);

  const handleClick = () => {
    setOpen(!isOpen);
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        Click Me
      </button>

      {isOpen && <div>Content</div>}
    </div>
  );
};

export default App;

总之,不管这个按钮在它的onClick处理程序上毕竟执行什么,你可能想为它创建一个可重用的组件。因此,我们将提取它作为一个新的函数组件,并将必要的道具传递给它:

import * as React from 'react';

const App = () => {
  const [isOpen, setOpen] = React.useState(false);

  const handleClick = () => {
    setOpen(!isOpen);
  };

  return (
    <div>
      <Button onClick={handleClick}>Toggle</Button>

      {isOpen && <div>Content</div>}
    </div>
  );
};

const Button = ({ onClick, children }) => {
  return (
    <button type="button" onClick={onClick}>
      {children}
    </button>
  );
};

export default App;

我们的Button组件现在是一个可重复使用的组件。例如,如果你在React中给你的输入字段一些CSS样式,那么在你的React项目中使用的每个Button组件都会使用同样的样式。

如果你现在想创建一个按钮组,你可以使用多个Button组件并排使用:

import * as React from 'react';

const App = () => {
  const [isOpen, setOpen] = React.useState(false);

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div>
      <Button onClick={handleOpen}>Open</Button>
      <Button onClick={handleClose}>Close</Button>

      {isOpen && <div>Content</div>}
    </div>
  );
};

const Button = ({ onClick, children }) => {
  return (
    <button type="button" onClick={onClick}>
      {children}
    </button>
  );
};

export default App;

从这里,你可以用许多功能来扩展你的Button组件。例如,类型不一定是按钮,但可以是submit ,用于处理React中的表单。因此,我们可以让外部的开发者为Button传递一个可选的type 道具,如果没有传递的话,内部默认为button

const Button = ({ type = 'button', onClick, children }) => {
  return (
    <button type={type} onClick={onClick}>
      {children}
    </button>
  );
};

或者你可以在Button组件不应该被点击的时候给它传递一个disabled 的道具。因为如果不提供的话,它的默认值是undefined ,所以按钮元素不会被禁用:

const Button = ({ type = 'button', disabled, onClick, children }) => {
  return (
    <button type={type} disabled={disabled} onClick={onClick}>
      {children}
    </button>
  );
};

然而,向Button组件传递所有这些额外的信息是很麻烦的。在一个完美的世界里,所有这些信息应该被Button组件接受,就像我们使用一个单纯的按钮元素一样。我们可以通过使用JavaScript的rest destructuring来实现React的props:

const Button = ({ type = 'button', onClick, children, ...rest }) => {
  return (
    <button type={type} onClick={onClick} {...rest}>
      {children}
    </button>
  );
};

现在,无论我们把一个disabled 布尔值还是一个style 对象传给Button组件,在内部它都会把它传给按钮元素。这样一来,Button元素的行为就和按钮元素相似。所有更明确的东西,比如onClick处理程序或type 道具的默认值,都需要明确写在Button组件的函数签名中。