React Hooks实现模糊搜索demo(ZUCC智能终端与移动应用开发lab6)
react hooks实现模糊搜索demo
分析ReactInAction01示例的数据状态控制和组件关系
组件关系
数据状态控制
完整代码
App.js
import React, { Component } from 'react';
import Table from './lab1/table'
import './lab1/table.css'
function App() {
return (
<>
<Table></Table>
</>
);
}
export default App;
table.js
import React ,{useState} from 'react';
import TableHeader from './tableHeader'
import TableBody from './tableBody'
import Form from './form';
function Table() {
const [person,setPerson] = useState([
{name:'zjx',job:'teacher'},
{name:'zs',job:'student'}
])
const deleteItem = (index)=>{
console.log("收到删除操作"+index)
console.log(person[index])
setPerson(()=>person.filter((item,i)=>i!=index)
)
}
const addItem = (item)=>{
console.log("成功接收到数据");
console.log(item);
setPerson(()=>{
return[
...person,item
] //这里返回的是一个数组,一开始以为是对象,所以一直报错
})
}
return (
<>
<table>
<TableHeader></TableHeader>
<TableBody
person = {person}
deleteItem = {deleteItem}
>
</TableBody>
</table>
<Form addItem = {addItem}></Form>
</>
)
}
export default Table;
tableHeader
import React from 'react';
function TableHeader() {
return (
<thead>
<tr>
<th>Name</th>
<th>Job</th>
<th>操作</th>
</tr>
</thead>
);
}
export default TableHeader;
tableBody.js
import React ,{useState} from 'react'
function TableBody(props) {
// const state = [{name:'zjx',job:'teahcer'}]
// const person = useContext(PersonValue)
// const [person,setPerson] = useState(props.character)
const removeItem = (index)=>{
props.deleteItem(index)
}
const rows = props.person.map((item,index) =>{
return (
<tr key={index}>
<th>{item.name}</th>
<th>{item.job}</th>
<th> <button onClick = {()=>removeItem(index)}>移除</button> </th>
</tr>
)
})
return (
<tbody>
{rows}
</tbody>
);
}
export default TableBody;
form.js
import React,{useState} from 'react';
function Form(props) {
const [form,setForm] = useState({name:'',job:''})
const handleChange = (e)=>{
const target = e.target;
console.log(e);
setForm(()=>{
return {
...form,
[target.name]:target.value, //key-value key是target.value所对应的属性名
}
})
console.log(form);
}
// console.log(props)
const submitAdd = ()=>{
// console.log(111);
props.addItem(form);
}
return (
<form>
{/* <p>{form.name}</p> */}
<label htmlFor="name">Name</label>
<input type="text" name="name" placeholder="请输入姓名" value={form.name} onChange={(e)=>handleChange(e)} />
<label htmlFor="job">Job</label>
<input type="text" name="job" placeholder="请输入工作" value={form.job} onChange={(e)=>handleChange(e)}/>
<button type = "button" onClick = {submitAdd}>submit</button>
{/* 这里必须设置一下button的类型不然会默认为submit导致刷新页面 */}
</form>
);
}
export default Form;
table.css
存放所有组件的css
table{
border-collapse: collapse;
border-spacing: 0;
width: 100%;
max-width: 100%;
}
thead th{
border-bottom: 2px solid #dedede;
}
tbody th{
border-bottom: 2px solid #dedede;
}
td{
border-bottom: 1px solid #dedede;
}
th,td{
text-align:left;
padding: .5rem;
}
button{
background-color: pink;
}
form{
width: 100%;
height: 20%;
display: flex;
flex-direction: column;
text-align: left;
}
label{
display:block;
width: 100%;
/* margin-bottom: .5rem; */
}
input{
margin: .5rem 0 ;
width: 70%;
height: 6vh;
}
form button {
width: 10rem;
height: 2rem;
font-size: 1rem;
}
一些知识点和坑
useState中setState的返回值(添加元素)
我定义表单的状态值为一个数组,他的单个元素是一个对象
{
name:'',
job:''
}
那么在调用setPerson返回的时候就要返回对应的数据类型——数组
const addItem = (item)=>{
console.log("成功接收到数据");
console.log(item);
setPerson(()=>{
return[
...person,item
] //这里返回的是一个数组,一开始以为是对象,所以一直报错
})
}
其中…person是将这个数组解构,后面添加新元素item
这是react中添加新元素的惯用手法
useState中通过set函数删除元素
子组件调用父组件删除元素的函数,同时传入要删除元素的下标
<th> <button onClick = {()=>removeItem(index)}>移除</button> </th>
父组件通过filter函数遍历元素,返回一个新的数组,作为setPerson的新的状态值返回
const deleteItem = (index)=>{
console.log("收到删除操作"+index)
console.log(person[index])
setPerson(()=>person.filter((item,i)=>i!=index)
)
}
可以写成这样看起来更直观
setPerson(()=>{
return person.filter((item,i)=>{
return i!=index
})
})
useState中input的双向绑定
不同的是useState定义的状态变量是一个对象形式
<input type="text" name="name" placeholder="请输入姓名" value={form.name} onChange={(e)=>handleChange(e)} />
<input type="text" name="job" placeholder="请输入工作" value={form.job} onChange={(e)=>handleChange(e)}/>
const handleChange = (e)=>{
const target = e.target;
console.log(e);
setForm(()=>{
return {
...form,
[target.name]:target.value, //key-value key是target.value所对应的属性名
}
})
console.log(form);
}
返回一个对象,将form的对象解构,同时返回一个属性(name或者job)覆盖form中的name或job以此达到更新的目的
setForm(()=>{
return {
...form,
[target.name]:target.value, //key-value key是target.value所对应的属性名
}
对象是key-value形式,这种写法就是根据value值找到对应的key,以此进行赋值
也就是说我们在name的输入框中输入zjx,那么target.value就是value(zjx),他所对应的key就是input所绑定的name属性也就是target.name(name)
[target.name]:target.value, //key-value
函数式组件
const rows = props.person.map((item,index) =>{
return (
<tr key={index}>
<th>{item.name}</th>
<th>{item.job}</th>
<th> <button onClick = {()=>removeItem(index)}>移除</button> </th>
</tr>
)
})
button点击之后刷新页面
<button type = "" onClick = {submitAdd}>submit</button>
一开始这么写提交按钮,没有表明type的类型,它默认为我们问submit类型,会刷新网页
改成下述写法
<button type = "button" onClick = {submitAdd}>submit</button>
编写如下程序SearchStudentApp:
a.程序包含一个学生列表页,页面中有一个搜索框,一个搜索按钮,一个数据显示表(包含学生学号、姓名、性别、班级四列),一个数据生成按钮
b.初始化时数据列表为空
c.点击数据生成按钮自动生成50行数据
d.在输入框中可以按照学生姓名模糊检索列表数据,并且更新表格为只显示符合检索条件的数据
使用json生成器快速生成50条数据
JSON Generator – Tool for generating random data (json-generator.com)
完整代码
studentTable.js
import React,{useState,useEffect} from 'react';
import TableBody from './TableBody';
import TableHeader from './TableHeader';
import SearchInput from './SearchInput'
function StudentTable() {
const [data,setData] = useState([
{}
])
const [init,setInit] = useState([
{}
]);
const loadData = (d)=>{
console.log("收到数据")
setData(d);
console.log(data);
setInit(d); //定义初始化数据
}
const search = (searchName)=>{
console.log("接收到搜索");
console.log(searchName);
setData(()=>init.filter((item)=>{ //在初始化数据中搜索 保证一直是全局搜索
return item.name.toLowerCase().indexOf(searchName.toLowerCase())>=0}))
}
return (
<>
<SearchInput loadData = {loadData} search = {search}></SearchInput>
<table>
<TableHeader></TableHeader>
<TableBody data = {data} ></TableBody>
</table>
</>
);
}
export default StudentTable;
searchInput.js
import React,{useState} from 'react';
// import '../../public/data.json'
function SearchInput(props) {
const data =
[
{
id: 32001682,
name: "Rachel",
gender: "female",
class: "2003"
},
{
id: 32001858,
name: "Mona",
gender: "female",
class: "2001"
},
{
id: 32001592,
name: "Gwendolyn",
gender: "female",
class: "2002"
},
{
id: 32001487,
name: "Mcfadden",
gender: "male",
class: "2001"
},
{
id: 32001862,
name: "Coleen",
gender: "female",
class: "2003"
},
{
id: 32001729,
name: "Austin",
gender: "male",
class: "2004"
},
{
id: 32001352,
name: "Vickie",
gender: "female",
class: "2002"
},
{
id: 32001613,
name: "Finley",
gender: "male",
class: "2002"
},
{
id: 32001983,
name: "Mandy",
gender: "female",
class: "2003"
},
{
id: 32001063,
name: "Barton",
gender: "male",
class: "2002"
},
{
id: 32001323,
name: "Melanie",
gender: "female",
class: "2002"
},
{
id: 32001424,
name: "Leticia",
gender: "female",
class: "2001"
},
{
id: 32001679,
name: "Candace",
gender: "female",
class: "2004"
},
{
id: 32001417,
name: "Cleo",
gender: "female",
class: "2001"
},
{
id: 32001221,
name: "Cathy",
gender: "female",
class: "2002"
},
{
id: 32001906,
name: "Angelita",
gender: "female",
class: "2001"
},
{
id: 32001338,
name: "Buchanan",
gender: "male",
class: "2001"
},
{
id: 32001348,
name: "Lenora",
gender: "female",
class: "2001"
},
{
id: 32001434,
name: "Inez",
gender: "female",
class: "2002"
},
{
id: 32001691,
name: "Jewell",
gender: "female",
class: "2002"
},
{
id: 32001616,
name: "Lesley",
gender: "female",
class: "2003"
},
{
id: 32001567,
name: "Dunn",
gender: "male",
class: "2004"
},
{
id: 32001902,
name: "Hall",
gender: "male",
class: "2004"
},
{
id: 32001418,
name: "Jacquelyn",
gender: "female",
class: "2004"
},
{
id: 32001618,
name: "Nichole",
gender: "female",
class: "2003"
},
{
id: 32001039,
name: "Carly",
gender: "female",
class: "2004"
},
{
id: 32001483,
name: "Barker",
gender: "male",
class: "2001"
},
{
id: 32001651,
name: "Randall",
gender: "male",
class: "2002"
},
{
id: 32001925,
name: "Madeleine",
gender: "female",
class: "2003"
},
{
id: 32001794,
name: "Kathie",
gender: "female",
class: "2002"
},
{
id: 32001843,
name: "Lavonne",
gender: "female",
class: "2004"
},
{
id: 32001714,
name: "Bond",
gender: "male",
class: "2002"
},
{
id: 32001196,
name: "Kasey",
gender: "female",
class: "2004"
},
{
id: 32001658,
name: "Jeanie",
gender: "female",
class: "2001"
},
{
id: 32001500,
name: "Bentley",
gender: "male",
class: "2004"
},
{
id: 32001285,
name: "Millie",
gender: "female",
class: "2004"
},
{
id: 32001531,
name: "Bonita",
gender: "female",
class: "2004"
},
{
id: 32001449,
name: "Millicent",
gender: "female",
class: "2002"
},
{
id: 32001049,
name: "Jenna",
gender: "female",
class: "2004"
},
{
id: 32001374,
name: "Rowena",
gender: "female",
class: "2001"
},
{
id: 32001966,
name: "Kenya",
gender: "female",
class: "2003"
},
{
id: 32001131,
name: "Aida",
gender: "female",
class: "2001"
},
{
id: 32001010,
name: "Oneill",
gender: "male",
class: "2004"
},
{
id: 32001070,
name: "Schultz",
gender: "male",
class: "2004"
},
{
id: 32001419,
name: "Aguirre",
gender: "male",
class: "2002"
},
{
id: 32001684,
name: "Sweet",
gender: "male",
class: "2002"
},
{
id: 32001931,
name: "Maritza",
gender: "female",
class: "2003"
},
{
id: 32001376,
name: "Kelley",
gender: "male",
class: "2003"
},
{
id: 32001800,
name: "Charlotte",
gender: "female",
class: "2003"
},
{
id: 32001344,
name: "Reyna",
gender: "female",
class: "2001"
}
]
const [searchName,setSearch] = useState('')
const getData = ()=>{
console.log(data);
pullData(data);
// fetch('D:\react-project\reactStudy\public\data.json')
// .then(response=>response.json())
// .then(response =>{console.log(response)})
}
const pullData = (d)=>{
props.loadData(d);
}
const handleChange = (e)=>{
console.log(e.target.value)
setSearch(e.target.value);
}
const handleSearch = ()=>{
console.log("pull")
props.search(searchName)
}
return (
<div className="search">
<input type="text" name="searchName" value={searchName} onChange={(e)=>handleChange(e)}/>
<button type="button" onClick={()=>handleSearch()} >搜索数据</button>
<button onClick={()=>getData()}>生成数据</button>
</div>
);
}
export default SearchInput;
tableHeader.js
function TableHeader() {
return (
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>班级</th>
</tr>
</thead>
);
}
export default TableHeader;
tableBody.js
function TableBody(props) {
const rows = props.data.map((item,index)=>{
return (
<tr key={index}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.gender}</td>
<td>{item.class}</td>
</tr>
)
})
return (
<tbody>
{rows}
</tbody>
);
}
export default TableBody;
效果
点击生成数据:
查找:
遇到的坑
json
生成的json导入有问题,为了简便,将数据直接定义在组件中
模糊搜索
将搜索的字符和数据库中的字符统一转化成小写toLowCase()
连续搜索
连续搜索应该一直是全局搜索,但是一开始的写法,每次搜索都是在上一次搜索到的数据基础上再进行搜索,这导致数据越来越少
解决方法就是定义一个初始状态数据存放所有数据,初次导入数据data和init的值都一样,搜索的时候在init中搜索
const [data,setData] = useState([
{}
])
const [init,setInit] = useState([
{}
]);
setData(()=>init.filter((item)=>{ //在初始化数据中搜索 保证一直是全局搜索
return item.name.toLowerCase().indexOf(searchName.toLowerCase())>=0}))
setState的解构问题
因为数据是以数组的形式存储,同时每个单元都是一个对象
如果setState()传入的元素和定义状态值的数据类型相同就不需要解构
更多推荐
所有评论(0)