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

下面就开始吧。首先创建一个新的 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
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!