8

用 React Hooks 做一个搜索栏

 4 years ago
source link: https://www.infoq.cn/article/qMfJOPSgRDf4rPCLqiGJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

bEnAFzV.gif

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

复制代码

npxcreate-react-appcontacts-list

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

复制代码

code.

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

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

复制代码

importReact, { useState }from"react";
import{ Numbers }from"./components/Numbers";
exportconstApp =()=>{
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>
<Numberspersons={persons}/>
</div>
);
};
export default App;

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

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

复制代码

importRect, { useStae }from"react";
exportconstNumbers =props=>{
// word 会跟踪 filter box 内输入的任何更改
const[word, setword] = useState("");
// filterdisplay 会基于 search 来显示更新的列表,其默认状态是我们的 persons 列表 prop
const[filterDispllay, setFilterDisplay] = useStae(props.persons);
// handleChange 每次运行时在输入字段都会有一个更改
consthandleChange =e=>{
// 在一个新数组中存放原始列表,将所有人名转为小写字母,因为我们不知道用户要输入什么格式;然后我们返回 OldList 作为一个对象数组,来存放这个更改的列表
letoldList = props.persons.map(person=>{
return{name: person.name.toLowerCase(),number: person.number };
});
// 如果输入栏不为空,则运行以下代码;否则,setFilterDisplay 设为原始列表 prop
if(e !=="") {
letnewList =[];
// 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:<inputonChange={e=>handleChange(e.target.value)} />
{filterDisplay.map((person, i) => (
<divkey={i}>
<li>
{person.name}  
<span>{person.number}</span>
</li>
</div>
))}
</div>
);
};

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

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

复制代码

importReactfrom"react";
exportconstFilter =({ value, handleChange }) =>{
return(
<div>
filter:<inputvalue={value}onChange={handleChange}/>
</div>
);
};

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

复制代码

importReactfrom"react";
exportconstNumbers =({ persons }) =>{
return(
<div>
<hl>Numbers</hl>
{person.map((person, i) => (
<divkey={i}>
<li>
{person.name}  
<span>{person.number}</span>
</li>
</div>
))}
</div>
);
};

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

复制代码

importReact, { 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);
letoldList = persons.map(person => {
return{name: person.name.toLowerCase(),number: person.number};
});

if(word !=="") {
letnewList = [];

newList = oldList.filter(person =>
person.name.includes(word.toLowerCase())
);

setFilterDisplay(newList);
}else{
setFilterDisplay(persons);
}
};

return(
<div>
<Filtervalue={word}handleChange={e => handleChange(e.target.value)}/>
<Numberspersons={word.length <1? persons : filterDisplay}/>
</div>
);
};
exportdefaultApp;

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

英文原文

How to Build a Search Bar in React With React Hooks


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK