React Hooks是React生态圈里边最火的新特性了。它改变了原始的React类的开发方式,改用了函数形式,通过一个小案例,理解对react hook的认知
安装react脚手架
create-react-app react-hook
创建一个组件FileSearch
在组件中引入react hook api
import React, { useState, useEffect} from 'react'
函数编写,useState
是react自带的一个hook函数,它的作用是用来声明状态变量。分别是声明、读取、使用(修改)。
- 在这定义
inputAction
用于控制切换显示和隐藏。value
定义input值,FileSearch 接收从其他组件传过来 值和方法。 - inputAction 根据
true
和false
来切换
const FileSearch = ({ title, onFileSearch }) => {
const [inputAction, setInputAction] = useState(false)
const [value, setValue] = useState('')
return (
<div className="alert alert-primary">
{!inputAction && (
<div className="d-flex justify-content-between align-items-center">
<span>{title}</span>
<button
type="button"
className="btn btn-primary"
onClick={() => {
setInputAction(true)
}}
>
搜索
</button>
</div>
)}
{inputAction && (
<div className="row">
<input
className="form-control col-8"
value={value}
ref={inputEl}
onChange={e => {
setValue(e.target.value)
}}
/>
<button
type="button"
className="btn btn-primary col-4"
>
关闭
</button>
</div>
)}
</div>
)
}
export default FileSearch
引入使用
在app组件引入这个组件,
import FileSearch from './components/FileSearch'
在页面中使用
<FileSearch
title="React Hook"
onFileSearch={value => {
console.log(value)
}}
/>
搜索框事件
seEffect用于处理组件中的effect,通常用于请求数据,事件处理,订阅等相关操作。
- 在一些业务中,在input框中,输入内容的时候,一般喜欢按回车键,完成一些操作,
useEffect(() => {
const handleInputEvent = event => {
const { keyCode } = event
if (keyCode === 13 && inputAction) {
// 键盘回车键
onFileSearch(value)
setValue('')
} else if (keyCode === 27 && inputAction) {
// 键盘esc
closeSearch(event)
}
}
document.addEventListener('keyup', handleInputEvent)
return () => {
document.removeEventListener('keyup', handleInputEvent)
}
})
- 在键盘按住ESC键的时候,触发清空内容,定义一个
closeSearch
方法
//清空内容
const closeSearch = e => {
e.preventDefault()
setInputAction(false)
setValue('')
}
input聚焦方法
通过hook一个useRef
可以实现,当我们点击搜索按钮切换到input框中,自动聚焦。
useRef 返回一个可变的 ref 对象,其 current
属性被初始化为传入的参数(initialValue)返回的 ref 对象在组件的整个生命周期内保持不变。
onst inputEl = useRef(null);
在input框中绑定ref
<input ref={inputEl} />
通过useEffect去实现,第二个参数,一定要写是在inputAction
存在的时候执行这个,不然就会一直执行
useEffect(() => {
if (inputAction) {
// current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus()
}
}, [inputAction])
最终所有的代码
import React, { useState, useEffect, useRef } from 'react'
const FileSearch = ({ title, onFileSearch }) => {
const [inputAction, setInputAction] = useState(false)
const [value, setValue] = useState('')
const inputEl = useRef(null)
//清空内容
const closeSearch = e => {
e.preventDefault()
setInputAction(false)
setValue('')
}
useEffect(() => {
const handleInputEvent = event => {
const { keyCode } = event
if (keyCode === 13 && inputAction) {
// 键盘回车键
onFileSearch(value)
setValue('')
} else if (keyCode === 27 && inputAction) {
// 键盘esc
closeSearch(event)
}
}
document.addEventListener('keyup', handleInputEvent)
return () => {
document.removeEventListener('keyup', handleInputEvent)
}
})
// input聚焦
useEffect(() => {
if (inputAction) {
// current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus()
}
}, [inputAction])
return (
<div className="alert alert-primary">
{!inputAction && (
<div className="d-flex justify-content-between align-items-center">
<span>{title}</span>
<button
type="button"
className="btn btn-primary"
onClick={() => {
setInputAction(true)
}}
>
搜索
</button>
</div>
)}
{inputAction && (
<div className="row">
<input
className="form-control col-8"
value={value}
ref={inputEl}
onChange={e => {
setValue(e.target.value)
}}
/>
<button
type="button"
className="btn btn-primary col-4"
onClick={closeSearch}
>
关闭
</button>
</div>
)}
</div>
)
}
export default FileSearch