本文最初发布于 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}
<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}
<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
更多内容推荐
17|推荐系统前端:如何用一个界面展示我们的成果?
在前面的课程中,我们使用Flask搭建了一个非常简单的HTTP服务,也提供了推荐列表和注册登录相关的接口。本节课我们将继续沿着这条思路,将它们用前端界面的形式展现出来。
2023-05-24
js 异步编程面试题你能答上来几道
在上一节中我们了解了常见的es6语法的一些知识点。这一章节我们将会学习异步编程这一块内容,鉴于异步编程是js中至关重要的内容,所以我们将会用三个章节来学习异步编程涉及到的重点和难点,同时这一块内容也是面试常考范围。
2022-10-19
js 进阶手写常见函数
无论是学习react还是vue,它们都是js的应用框架。剥去他们的壳子看到的始终是js,所以作为一个前端大厨必须要熟练掌握好js这个大勺,才能烧出一顿好菜
2022-10-03
说说你对 Vue 的 keep-alive 的理解
在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,也不会进行重新初始化组件。
2022-10-05
04|Vue 概览:Vue 哪些内容是你必须要掌握的?
这节课我们就来揭开Vue的神秘面纱,一起来看看Vue里必须掌握的知识点,以及怎样学习Vue才更加高效。
2023-05-01
07|路由设计:如何借助 Vue Router 设计出更合理的路由?
路由的配置管理在Vue框架开发中非常重要,是我们完成后续各功能模块开发的前提。
2023-05-08
网站开发进阶(六十一)详解 js 中 Number()、parseInt() 和 parseFloat() 的区别
本文主要对js中Number()、parseInt()和parseFloat()的区别进行详细介绍。
2022-05-13
APICloud AVM 框架列表组件 list-view 的使用、flex 布局教程
avm.js 是APICloud 推出的多端开发框架。使用 avm.js 一个技术栈可同时开发 Android & iOS 原生 App、小程序和 iOS 轻 App,且多端渲染效果统一;全新的 App 引擎 3.0 不依赖 webView,提供百分百的原生渲染,保障 App 性能和体验与原生 App 一致。
2022-02-09
你的 App 是信息化时代的还是数字化时代的
“数字化转型”,每家企业都在大讲特讲。可是对于很多人来说,数字化也就是信息化的时髦说法而已,换了个马甲罢了。
2022-06-02
Vue3 组件开发之: 父子组件之间的通信方式🔥
Hello,又见面了,我是渔戈! 今天我们来来讲讲Vue的组件化开发中父子组件之间的通信方式! 1.认识组件的嵌套 我们之前讲Vue的时候是将所有的逻辑放到一个App.vue中: 在之前的案例中,我们只是创建了一个组件App; 如果我们一个应用程序将所有的逻辑都放在
2022-10-25
Dva.js 新手入门指南
Dva.js 入门指南
2022-08-03
前端【js】学习 JavaScrip 心得
先来看看JavaScript1、生产出一大堆库:jQuery、MooTools、Prototype、Dojo、YUI、ExtJS、ZeptoJS......2、生产出一大堆框架:AngularJS、VueJS、ReactJS、EmberJS、NuxtJS、ThreeJS......3、生产出一大堆衍生语言:TypeScript、JSX、CoffeeScript......4、E
2022-05-14
11|DPlayer 播放器综合应用:怎样实现自己的第一个视频播放器?
这节课,我们一起来学习如何在视频平台中实现自己的第一个视频播放器。
2023-05-17
一天梳理完 React 所有面试考察知识点
性能优化,永远是面试的重点,性能优化对于 React 更加重要
2022-10-25
help.hybris.com 和 help.sap.com 网站的搜索实现
我使用help.hybris.com时,发现每次在搜索栏输入文字时,没有发出任何HTTP请求,那么这个自动完成的下拉框里的记录从哪里来的?我看了下实现,发现所有自动完成下拉框里的记录都是硬编码在searchsuggestion.js里:
2021-06-05
10 个打造 React.js App 的最佳 UI 框架
在本文中,我们将分享一些助你打造 React.js App 最佳的 UI 框架。它们具备你所需要的基本 React 组件,以及易用的 API,同时,在外观和体验上也非常棒。Have Fun !
2021-12-21
【百度技术分享】San 介绍以及在百度 APP 的实践
San是百度自研的高性能MVVM框架,它是一个快速、轻量、灵活的JavaScript组件框架,体积小巧,兼容性好,性能卓越,目前已落地百度APP包括搜索、feed、小程序等核心业务,服务于亿级用户,开源社区已超过36位贡献者,Star数量超过4.3K。
2021-02-05
特别加餐|用 ChatGPT 开发一个看板项目
有不少同学希望了解AI,尤其是生成式AI对前端开发工作和前端工程师意味着什么,我个人也在关注相关领域的进展,正好趁着这次加餐的机会,跟你交流一下我的想法。
2023-05-22
Vue.js 教程:构建一个特斯拉汽车余电计算器
那么,特斯拉上哪去领呢?
12|视频发布功能实现:怎样满足用户发布视频的需求?
这节课我们将会设计和实现视频发布功能,这是视频平台里最核心的一个模块。
2023-05-19
让所有人认同的文字称不上表达
推荐阅读
25. 销售提问之痛——跟客户聊了很多为何都是无效沟通?
2023-10-17
2024 年,你应该知道的 5 种 React 设计模式
21|部署一个鲜花网络电商的人脉工具(下)
2023-10-25
为什么说 Next.js 13 是一个颠覆性版本
答疑篇|前导篇 & 前端实战篇思考题答案
2023-07-19
2022 卡塔尔世界杯收官,中国 App 继续中东「征战」
2022-12-21
Angular 18 引入了 Zoneless 变更检测
后端
电子书
大厂实战PPT下载
换一换 麦玮嘉 | Seal 首席研发工程师
党宇航 | VAST 产品负责人
魏刚 | OPPO 机器学习部预估组负责人
评论