教程:FullStackOpen2022 / Part 7 / 自定义 hooks
本文以 routed-anecdotes 应用为例。对应练习 7.4-7.6。
1. React Hooks
React 提供了多种不同的 Hooks,其中最常用的是 useState
和 useEffect
,又比如 useImperativeHandle
,它允许组件向其他组件提供其功能。
Hook 不是普通的函数,在使用这些 Hooks 时,必须遵守某些规则或限制:
- 不要在循环、条件或嵌套函数中调用 Hooks。即,总是在 React 函数的顶层使用 Hooks。
- 不要从普通的 JavaScript 函数中调用 Hooks。即,可以从 React 函数组件调用,或从自定义 Hooks 中调用 Hooks。
有现有的 ESlint 规则 eslint-plugin-react-hooks
可以用来验证应用是否正确使用 Hooks。
更多信息可见:useHooks
2. Custom Hooks
React 提供了创建自定义的 Custom Hooks 的选项。
Custom Hooks 的主要目的是促进组件中使用的逻辑的重用,可以使用任何其他 Hooks。Custom Hooks 需要遵守 React Hooks 的规则,此外,名称必须以 use
这个词开头。
表单的每个字段都有自己的状态。为了使表单的状态与用户提供的数据保持同步,必须为每个输入元素注册一个适当的onChange处理程序。下面让试着自定义 useField
Hook 来简化表单的状态管理。
hooks/index.js:
import { useState } from 'react'
export const useField = (type) => {
const [value, setValue] = useState('')
const onChange = (event) => {
setValue(event.target.value)
}
const reset = () => {
setValue('')
}
return {
reset,
type,
value,
onChange,
}
}
该 Hook 接收输入字段的类型作为参数,返回输入所需的所有属性:其类型、值和 reset
与 onChange
处理程序。
这个 Hook 可以用以下方式使用:
const CreateNew = (props) => {
const { reset: content_reset, ...content } = useField('text')
const handleSubmit = (e) => {
e.preventDefault()
props.addNew({
content: content.value,
})
}
const handleReset = (e) => {
e.preventDefault()
content_reset()
}
return (
<div>
<h2>create a new anecdote</h2>
<form onSubmit={handleSubmit}>
<div>
content
<input {...content} />
</div>
<button type="submit">create</button>
<button type="button" onClick={handleReset}>
reset
</button>
</form>
</div>
)
}
关于代码中使用的 Spread Attributes,更多可见: