- 概念: 自定义hook是react中最新的组件代码复用方案
注意点: hook必须以use开头,并需要使用别的hook - 例子
1)useEffect
useEffect(() => {
fetch(`${apiUrl}/users`).then(async response => {
if (response.ok) {
setUsers(await response.json())
}
})
}, [])
改造后
export const useMount = (callback) => {
useEffect(() => {
callback();
}, []);
useMount(() => {
fetch(`${apiUrl}/users`).then(async response => {
if (response.ok) {
setUsers(await response.json())
}
})
})
- useDebounce
常用debounce
const debounce = (func, delay) => {
let timeout;
return (...param) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
func(...param);
}, delay);
}
}
const log = debounce(() => console.log('call'), 5000)
log()
log()
log()
但在以下场景使用并不优雅
const [param, setParam] = useState({
name: '',
personId: ''
})
useEffect(() => {
fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`).then(async response => {
if (response.ok) {
setList(await response.json())
}
})
}, [param])
通过useDebounce来
export const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
// 每次在value变化以后,设置一个定时器
const timeout = setTimeout(() => setDebouncedValue(value), delay);
// 每次在上一个useEffect处理完以后再运行
return () => clearTimeout(timeout);
}, [value, delay]);
return debouncedValue;
};
const [param, setParam] = useState({
name: '',
personId: ''
})
const debouncedParam = useDebounce(param, 2000)
useEffect(() => {
fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(debouncedParam))}`).then(async response => {
if (response.ok) {
setList(await response.json())
}
})
}, [debouncedParam])
- useArray
import { useArray, useMount } from "utils";
import React, { useState } from "react";
export const TsReactTest = () => {
const persons: { name: string; age: number }[] = [
{ name: "jack", age: 25 },
{ name: "ma", age: 22 },
];
const { value, clear, removeIndex, add } = useArray(persons);
return (
<div>
{value.map((person, index) => (
<div style={{ marginBottom: "30px" }}>
<span style={{ color: "red" }}>{index}</span>
<span>{person.name}</span>
<span>{person.age}</span>
</div>
))}
{/* 点击以后清空列表*/}
<button style={{ marginBottom: "50px" }} onClick={() => clear()}>
clear
</button>
{/* 点击以后删除第一项*/}
<button onClick={() => removeIndex(0)}>remove 0</button>
{/* 点击以后增加 john */}
<button onClick={() => add({ name: "john", age: 22 })}>add john</button>
</div>
);
export const useArray = <T>(initialArray: T[]) => {
const [value, setValue] = useState(initialArray);
return {
value,
setValue,
add: (item: T) => setValue([...value, item]),
clear: () => setValue([]),
removeIndex: (index: number) => {
const copy = [...value];
copy.splice(index, 1);
setValue(copy);
},
};
};
网友评论