如何制作一个简单的 React 搜索插件,发布到 npm并且部署到 Github 页面(上)

721 阅读5分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。

在本文中,我们将在React中编写一个简单的搜索插件。通过这篇文章,我希望能帮助开发者们了解如何使用 React 编写插件,将它们发布到npm并将演示部署到 Github 页面。

开始

我们将使用create-react-library,这是一个用于创建可重用反应库的 CLI。这个 CLI 有很多特性,将帮助我们为我们的插件生成样板。

要使用 create-react-library,我们需要全局安装它:

npm install -g create-react-library

上面的命令将全局安装 create-react-library,我们可以从任何目录生成一个新模块。要生成新目录,请在要引导插件的目录中键入以下命令:

create-react-library

上面的命令将询问有关您的模块的一些基本提示,一旦您回答它们,就会生成插件的样板。

现在,你需要运行插件(以查看您对其所做的任何更改)和示例。在一个选项卡中,你可以运行:

cd react-search-box && yarn start

而且,在另一个选项卡中,你需要运行示例应用程序:

cd react-search-box/example && yarn start

最后一个命令将运行一个导入插件的create-react-app项目。如果你对插件进行任何更改,它将反映在示例应用程序中。您可以通过访问http://localhost:3000查看插件的当前状态。

daNJKly2eX8HNgjW9aDn5PI3um-Rx1JVlaYf

使用create-react-library引导后插件的初始状态

设计输入框

让我们添加第一个基本功能:一个允许用户输入的输入框。

import React, { Component } from 'react'import PropTypes from 'prop-types'
import styles from './styles.css'
export default class ReactSearchBox extends Component {  static propTypes = {    /**     * value: The default value for the input box.     * placeholder: The placeholder text for the input box.     */    value: PropTypes.string,    placeholder: PropTypes.string  }
  state = {    value: ''  }
  componentDidMount() {    const { value } = this.props
    this.setState({      value: value    })  }
  handleInputChange = e => {    const { value } = e.target
  this.setState({      value: value    })  }
  inputNode = () => {    /**     * This function is responsible for rendering the input box.     * The input box acts as a source of entry for the data from the user.     */    const { placeholder } = this.props    const { value } = this.state
    return (      <input        className={styles.input}        type='text'        placeholder={placeholder}        value={value}        onChange={this.handleInputChange}      />    )  }
  render() {    return <div className={styles.container}>{this.inputNode()}</div>  }}

在上面的代码中,我们创建了一个输入元素,它有一个className属性、一个type属性、一个placeholder属性、一个value属性和一个onChange处理程序。其中大部分是非常基本的道具。唯一有趣的道具是onChange每当用户在输入框中输入时触发的道具。

每当输入框发生变化时,我们都会调用该handleInputChange函数。handleInputChange函数获取事件作为它的参数。我们在这里使用ES6 箭头函数。所以,我们不需要显式地绑定this函数handleInputChange。你可以阅读James K Nelson的何时应该在 React中使用箭头函数

由于我们有一个value作为属性传递给输入框的状态,value因此只要输入框通过该handleInputChange函数发生变化,我们就会更新该状态。

handleInputChange = e => {  const { value } = e.target
  this.setState({    value  })}

如果你访问http://localhost:3000,你会在屏幕上看到一个输入框。您可以在输入框中输入,值将得到更新。

P5R0CV2siS1BaLpAvp3FW7c5Y8wAcMcs63fA

输入框初始状态

如果您签入React Developer Tools,您会看到输入框的值正在更新。

hB2qoFsdmF90pz-DdbiGWLVJ-GcBlmHlPsWP

RDdZ2Gk38kACwg6jmrL6sLQlUqtLUuQB1GiF

这就是我们输入框所需的所有功能。data接下来,我们将设计一个下拉列表,一旦用户在输入框中键入的字符串与将通过prop提供给我们的插件的任何记录匹配,就会出现该下拉列表。

设计下拉菜单

在本节中,我们将实现一个下拉列表,该下拉列表将显示一个与用户在输入框中键入的字符串匹配的记录数组。初始记录数组将使用data我们将首先实现的道具提供。

import React, { Component } from "react";import ReactSearchBox from "react-search-box";
export default class App extends Component {  data = [    {      key: "john",      value: "John Doe"    },    {      key: "jane",      value: "Jane Doe"    },    {      key: "mary",      value: "Mary Phillips"    },    {      key: "robert",      value: "Robert"    },    {      key: "karius",      value: "Karius"    }  ];
  render() {    return (      <div className="container">        <ReactSearchBox          placeholder="Placeholder"          value="Doe"          data={this.data}        />      </div>    );  }}

我们的插件应该像上面的代码块一样被导入和定义。您导入ReactSearchBox,然后将对象data数组(在本例中为数组)传递给ReactSearchBox.

value现在,如果将prop 传递给我们的插件,我们将呈现下拉列表。稍后,如果 prop 中的任何记录data与提供的 prop 匹配,我们将重构我们的组件以显示下拉列表value

我们的插件现在看起来像下面这样:

import React, { Component } from 'react'import PropTypes from 'prop-types'
import styles from './styles.css'
export default class ReactSearchBox extends Component {  static propTypes = {    /**     * value: The default value for the input box.     * placeholder: The placeholder text for the input box.     * data: An array of objects which acts as the source of data for the dropdown.     */    value: PropTypes.string,    placeholder: PropTypes.string,    data: PropTypes.array.isRequired  }
  static defaultProps = {    /**     * Set data prop as an empty array in case it's not passed.     */    data: []  }
  state = {    value: ''  }
  componentDidMount() {    /**     * This function is the same as before     */    }
  handleInputChange = e => {    /**     * This function is the same as before     */    }
  inputNode = () => {    /**     * This function is the same as before     */  }
  dropdownNode = () => {    /**     * This function is responsible for rendering the dropdown.     */    const { data } = this.props
    return (      <div className={`react-search-box-dropdown ${styles.dropdown}`}>        <ul className={styles.dropdownList}>          {data.map(record => {            return (              <li                key={record.key}                className={`react-search-box-dropdown-list-item ${                  styles.dropdownListItem                }`}              >                {record.value}              </li>            )          })}        </ul>      </div>    )  }
render() {    return (      <div className={styles.container}>        {this.inputNode()}        {this.dropdownNode()}      </div>    )  }}

下拉菜单的代码存在于dropdownNode函数中。基于data提供给我们插件的道具,我们正在创建一个li项目列表并在下拉列表中呈现。

如果我们访问http://localhost:3000/,我们将看到一个下拉菜单和一个输入框。


mGlZbD5-5b4zICli-oEy1trP5j5Z4HvJan73

这就是下拉菜单所需的所有功能。接下来,我们将重构我们的插件以仅在任何记录与用户将在输入框中键入的查询匹配时才呈现下拉菜单。