写点什么

用 React Hooks 做一个搜索栏

  • 2020-04-24
  • 本文字数:2539 字

    阅读完需:约 8 分钟

用React Hooks做一个搜索栏

本文最初发布于 Hackernoon 博客,经原作者授权由 InfoQ 中文站翻译并分享。


以下是我们将要构建的搜索框的动图。这是一个简单的搜索框,我们可以用它来搜索联系人列表。我们将使用函数式组件,而不是基于类的组件来实现它。



下面就开始吧。首先创建一个新的 React 应用:


npx create-react-app contacts-list 
复制代码


然后转到 contacts-list 目录。在你常用的代码编辑器中打开目录。就我而言,我使用的是 vscode,因此我要从命令行执行的操作是:


code .
复制代码


src 目录中创建一个名为 components 的新文件夹,并在其中创建一个 Numbers.js 文件。转到你的 App.js 文件并导入 Numbers.js 组件。


接下来我们需要创建一些人名,然后将这些人名作为 props 传递给 Numbers.js 组件来渲染。


import React, { useState } from "react";import { Numbers } from "./components/Numbers";export const App = () => {  const [persons] = useState([    { name: "Dayo Olorinla", number: "+234-1234-5678" },    { name: "Temi Otedola", number: "+234-9029-9229" },    { name: "Zlatan Ibile", number: "+234-1243-2345" },  ]);
return ( <div> <Numbers persons={persons} /> </div> );};export default App;
复制代码


现在在我们的 Numbers 组件中,我们将接收从 App 传递过来的 props,并使用它来显示 contacts list


参见下面的代码,其中包含每个步骤的解释说明。


import Rect, { useStae } from "react";export const Numbers = props => {// word 会跟踪 filter box 内输入的任何更改  const [word, setword] = useState("");// filterdisplay 会基于 search 来显示更新的列表,其默认状态是我们的 persons 列表 prop  const [filterDispllay, setFilterDisplay] = useStae(props.persons);// handleChange 每次运行时在输入字段都会有一个更改  const handleChange = e => {// 在一个新数组中存放原始列表,将所有人名转为小写字母,因为我们不知道用户要输入什么格式;然后我们返回 OldList 作为一个对象数组,来存放这个更改的列表  let oldList = props.persons.map(person => {    return { name: person.name.toLowerCase(), number: person.number };  });  // 如果输入栏不为空,则运行以下代码;否则,setFilterDisplay 设为原始列表 prop  if (e !== "") {    let newList =[];    // setWord 一直跟踪输入的任何更改    setWord(e);    // newList 是保存符合搜索参数的 persons 的数组    newList = oldList.filter(person =>// 我们调用 includes 方法并用小写传递进'word'状态,这会检查 oldList 是否包含名字中带有'word'的人名      person.name.includes(word.toLowerCase())    );// 我们会一直检查输入并返回 newList 数组。我们调用 setFilterDisplay 来在每次输入调整后更新状态      setFilterDisplay(newList);    }  };  return (    <div>      <hl>Number</hl>      filter: <input onChange={e => handleChange(e.target.value)} />      {filterDisplay.map((person, i) => (        <div key={i}>          <li>            {person.name} &nbsp;            <span>{person.number}</span>          </li>        </div>      ))}    </div>  );};
复制代码


最后,每次更新时,我们都会从 FilterDisplay 返回更新的信息。如果你和我一样想将搜索栏分成一个单独的组件,请继续看下去。下面我们来重构这个东西!将搜索拆分成一个单独的组件后,我们就可以在应用程序的其他组件中使用同样的搜索栏了。


首先我们创建一个 Filter 组件,在我们的 components 文件夹中将其命名为 Filter.js。它需要 2 个 props,分别用于输入值和 onChange 事件。


import React from "react";export const Filter = ({ value, handleChange }) => {  return (    <div>      filter: <input value={value} onChange={handleChange} />    </div>  );};
复制代码


接下来我们需要重构 Numbers.js 组件,让它只渲染过滤过的人员列表。它将接受一个 prop,也就是 list/array。


import React from "react";export const Numbers = ({ persons }) => {  return (    <div>      <hl>Numbers</hl>      {person.map((person, i) => (        <div key={i}>          <li>            {person.name} &nbsp;            <span>{person.number}</span>          </li>        </div>      ))}    </div>  );};
复制代码


回想一下,我们所有的状态都在 App 组件内管理,并作为 props 传递给我们的组件。最后,在 App 组件中我们将一个有状态值传递给 Filter 组件中的输入字段,还将传递一个 handleChange 方法,当输入字段中发生更改时将调用这个方法。


import React, { useState } from "react";import { Filter } from "./components/Filter";import { Numbers } from "./components/Numbers";export const App = () => {  const [word, setWord] = useState("");  const [persons] = useState([    { name: "Dayo Olorinla", number: "+234-1244-5678" },    { name: "Temi Otedola", number: "+234-9029-9229" },    { name: "Zlatan Ibile", number: "+234-1243-2345" }  ]);  const [filterDisplay, setFilterDisplay] = useState([]);
const handleChange = e => { setWord(e); let oldList = persons.map(person => { return { name: person.name.toLowerCase(), number: person.number }; });
if (word !== "") { let newList = [];
newList = oldList.filter(person => person.name.includes(word.toLowerCase()) );
setFilterDisplay(newList); } else { setFilterDisplay(persons); } };
return ( <div> <Filter value={word} handleChange={e => handleChange(e.target.value)} /> <Numbers persons={word.length <1 ? persons : filterDisplay} /> </div> );};export default App;
复制代码


return 中,我们的 Numbers 组件将始终检查输入字段是否为空白。如果是的话就渲染原始的 Persons 数组,否则我们根据在输入字段中输入的内容渲染列表。就是这样,搞定!

英文原文

How to Build a Search Bar in React With React Hooks


2020-04-24 16:484442
用户头像
小智 让所有人认同的文字称不上表达

发布了 408 篇内容, 共 390.6 次阅读, 收获喜欢 1982 次。

关注

评论

发布
暂无评论
发现更多内容

数字孪生5G智慧工厂3D可视化云平台

2D3D前端可视化开发

物联网 可视化 数字孪生 智慧工厂 智能制造

火山引擎DataTester:跨境电商网站,如何快速实施AB测试 ?

字节跳动数据平台

大数据 A/B 测试 对比实验 数字化增长 企业号10月PK榜

负载均衡详解

天翼云开发者社区

负载均衡 服务器

MySQL的index merge(索引合并)导致数据库死锁分析与解决方案 | 京东云技术团队

京东科技开发者

MySQL 数据库 索引 企业号10月PK榜

使用 GitHub Action 自动更新 Sealos 集群的应用镜像

米开朗基杨

云原生 #go

开放原子开源基金会联合主办的2023 CCF中国开源大会即将开幕

开放原子开源基金会

开源 CCF

数据如何同步到云服务器

天翼云开发者社区

云计算 数据迁移

可制造性拓展篇│HDI(盲、埋孔)板压合问题

华秋电子

HDI

用友战略签约广联达,共同使能建筑行业企业高质量发展

用友BIP

建筑行业

Flink测试利器之DataGen初探 | 京东云技术团队

京东科技开发者

大数据 测试 flink sql 执行过程 企业号10月PK榜 DataGen

当HTAP已成标配,什么才是制胜关键?

MatrixOrigin

分布式数据库 云原生数据库 MatrixOrigin MatrixOne HTAP数据库

FinClip小程序技术,加速国产化应用新进程

FinClip

云网络对等连接产品的高可用保证

天翼云开发者社区

网络 对等连接

淘天集团大模型应用十大挑战命题发布

阿里技术

AI 校招 AIGC 淘天

户外裸眼3D屏幕合适用什么规格

Dylan

3D LED显示屏 户外LED显示屏 led显示屏厂家

校源行丨开放原子开源基金会赴北京信息科技大学走访交流

开放原子开源基金会

以效率为导向:用ChatGPT和HttpRunner实现敏捷自动化测试(二) | 京东云技术团队

京东科技开发者

自动化测试 敏捷测试 HttpRunner ChatGPT 企业号10月PK榜

Trino容错模式深度测评与思考

华为云开发者联盟

大数据 后端 华为云 华为云开发者联盟 交互式分析

【华秋商城】海量现货库存 闪电发货

华秋电子

连接器

如何强制SQL走性能更优的hash join

华为云开发者联盟

数据库 sql 后端 华为云 华为云开发者联盟

从原理到实战,详解XXE攻击

华为云开发者联盟

安全 后端 华为云 华为云开发者联盟

战略引领 注重实绩 形成闭环——中国交建绩效管理创新与数智化实践

用友BIP

绩效管理

EVE-NG初次启动及WEB客户端访问

小魏写代码

软件测试/测试开发丨Python闭包与装饰器 学习笔记

测试人

Python 程序员 软件测试 自动化测试 测试开发

出版行业企业如何快速实现数智化转型?

用友BIP

Fast by BIP 出版行业

用React Hooks做一个搜索栏_大前端_adebola_InfoQ精选文章