正式定档!QCon 北京站改期为2024年4月11-13日,地点:北京·国测国际会议会展中心 >>> 了解详情
写点什么

用 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:482887
用户头像
小智 让所有人认同的文字称不上表达

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

关注

评论

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

字节跳动测试开发1,android小游戏开发

android 程序员 移动开发

架构实战营作业 -- 模块六

冬瓜茶

如果你是小白,想学Android;如果你是Android开发者,安卓开发快速上手

android 程序员 移动开发

字节跳动1面Too simple2面怀疑人生,宅家修炼“65天,flutter下拉列表

android 程序员 移动开发

字节跳动高工面试-Android-R如何访问文件、修改文件?你们对R适配了吗

android 程序员 移动开发

安卓-如何用正确的姿势监听Android屏幕旋转,flutter修改textfield内容

android 程序员 移动开发

如何教女友学编程?你先去洗澡,我构思一下,androidapp开发语言

android 程序员 移动开发

字节+谷歌超全Kotlin学习王炸笔记!Kotlin入门到精通,我的头条面试经历分享

android 程序员 移动开发

架构实战营作业 -- 模块五

冬瓜茶

架构实战营作业 -- 模块七

冬瓜茶

字节Android岗面试:Handler中有Loop死循环,为什么没有阻塞主线程

android 程序员 移动开发

安卓屏幕完美适配方案,组件化与插件化的差别在哪里

android 程序员 移动开发

安卓指纹对称加密及登录功能的实现,android面试简历

android 程序员 移动开发

如何学好设计,做好架构? 设计原则才是关键,精通android游戏开发

android 程序员 移动开发

如何正确的在 Android 上使用协程 ?,kotlin数组全排列

android 程序员 移动开发

字节跳动+京东+360,帮助程序员提高核心竞争力的30条建议

程序员 移动开发

字节跳动大神讲座:我们除了技术一无所有,2020Android程序员职业规划

android 程序员 移动开发

字节跳动抖音安卓客户端日常实习 3+1 面经(已 OC,贼厉害

android 程序员 移动开发

字节跳动面试,第三面挂了,这原因我服了,程序员进阶知识点

android 程序员 移动开发

字节跳动:必面题说一下Android消息机制,重要概念一网打尽

android 程序员 移动开发

学习Flutter,你需要了解的Dart 编码规范,sharedpreferences用法

android 程序员 移动开发

王者荣耀商城异地多活架构设计

Imaginary

字节跳动已经10万人了?渣本双非Android程序员怎么上车?

android 程序员 移动开发

安卓11来了,快!扶我起来,音视频开发书籍

android 程序员 移动开发

如何将项目提交到GitHub,mmkv如何保证进程安全

android 程序员 移动开发

字节跳动面试:对于Tersorflow你怎么理解的,有做过人工智能的应用吗

android 程序员 移动开发

妙用AccessibilityService黑科技实现微信自动加好友拉人进群聊

android 程序员 移动开发

如何才能更容易拿到大厂Offer?阿里大佬十年面试了-2000-人,总结了这7-条---

android 程序员 移动开发

如何自学Android gityuan ?,2021年互联网大厂Android面经总结

android 程序员 移动开发

如果你使用Jetpack中还没踩过这些坑,请务必收下这篇文章

android 程序员 移动开发

如何加载100M的图片却不撑爆内存,一张 100M 的大图,如何预防 OOM?

android 程序员 移动开发

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