vlambda博客
学习文章列表

没有什么是React Hooks(钩子函数)解决不了的(二)


在上一篇文章中,我们从理论和概念层面谈到了什么是钩子函数,钩子函数的存在必要性和优点,那么这篇文章我们从代码角度出发,看看怎样实现它。


我们尝试做一个如图所示的搜索框:



首先我们需要把这些candidate的信息放到state里面:


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组件:


import Rect, { useStae } from "react"; export const Numbers = props => {// word 会跟踪 filter box 内输入的任何更改 const [word, setword] = useState("");// filterdisplay 会基于 search 来显示更新的列表,其默认状态是我们的 persons 列表 prop        const [filterDisplay, 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> ); };


在这个numbers组件里,人名被作为Props传递进来。这样的话,我们就实现了这个简易filter了。






现在,让我们尝试重构这个组件,方面同学们理解钩子函数


首先我们需要创建一个Filter组件:


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


然后需要重构Numbers组件:


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组件内,方便管理。


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;


在这篇文章中,我们提到了最常用的,也是React自带的钩子函数:useState。FLAGeek的后台有同学留言说,在实际项目中,我们接触到的Hooks函数往往不只是useState。确实如此,那么下一篇文章,我们就来谈谈一些比较常见的钩子函数,以及他们的使用场景和相似点,敬请期待。


Reference: 

Hackernoon's Blog



- 课程咨询 -

添加FLAGeek小助手领取第五版LeetCode刷题分类手册


LeetCode刷题分类手册(转专业/零基础小白入门神器):


FLAGeek简历修改技巧与干货:


FLAGeek核心课程介绍(详情见官网 www.flageek996.com)

CS301A 算法基础快速入门(Java/Cpp)

CS301B 题型技巧与算法讲解(Java/Cpp)

CS403A LeetCode1-300题详解(Java/Cpp/Python)

CS403B LeetCode301-1000高频题详解(Java/Cpp)