1. 实现目的
- 将组件逻辑提取到可重用的函数中
- 实现同一套数据源管控不同的组件(子组件)
2. 自定义Hook的规范
- 自定义Hook是一个函数, 名称以
use
开头,采用小驼峰方式命名 useTag
- Hook内部可以调用其他的Hook
- 一个组件只能在最顶层使用Hook, 不要在循环,条件或嵌套函数中调用 Hook。 确保总是在你的 React 函数的最顶层以及任何 return 之前调用Hook
- 只能在React函数组件调用Hook
3. 自定义组件开发示例
3.1 最基本的钩子
import React, { useState } from 'react';
function useCounter(initialValue) {
const [count, changeCount] = useState(initialValue);
const decrease = () => {
changeCount(count - 1);
}
const increase = () => {
changeCount(count + 1);
}
const resetCounter = () => {
changeCount(0);
}
return [count, { decrease, increase, resetCounter }]
}
export default function myHooksView() {
const [count, controlCount] = useCounter(10);
return (
<div>
当前数量:{count}
<button onClick={controlCount.decrease}>减少</button>
<button onClick={controlCount.increase}>增加</button>
<button onClick={controlCount.resetCounter}>重置</button>
</div>
)
}
3.2 返回DOM与其他方法的钩子
import React, { ReactNode, useEffect, useState } from 'react';
function useModal(id: string | null) {
const [visible, changeVisible] = useState(false);
const [list, setList] = useState<number[]>([]);
useEffect(() => {
getData()
}, [id])
const toggleModalVisible:() => void = () => {
changeVisible(!visible);
};
const getData:() => void = () => {
setTimeout(() => {
setList([0, 9, 8])
}, 9)
}
const getEle:() => ReactNode = () => {
return <div>
这是子组件内容
</div>
}
const getEle1:() => ReactNode = () => {
return <div>
这是子组件3333内容
</div>
}
const getAsyncEle:() => ReactNode = () => {
return <div>
{
list.map((item) => {
return <div>{ item }</div>
})
}
</div>
}
const getAsyncFEle:() => ReactNode = () => {
console.log(id, 'sera')
return <div>
{
list.map((item) => {
return <div>{ item }</div>
})
}
</div>
}
return [getEle(), getEle1(), getAsyncEle(), getAsyncFEle(), {
toggleModalVisible,
}];
}
export default function HookDemo() {
const [id, setId] = useState<string | null>(null);
const [getEle, getEle1, getAsyncEle] = useModal(id);
useEffect(() => {
getData()
}, [])
const getData: () => void = () => {
setTimeout(() => {
setId('000')
}, 1000)
}
return (
<div>
{getEle}
{getEle1}
{getAsyncEle}
</div>
);
}