Custom Hook通常用于提取并复用代码;
Custom Hook是React中最新也是最优秀的组件代码复用方案;
已经学习的useState和useEffect两个是最基本的React自带Hook。在提到Custom Hook时,我们将能了解到useMount和useDebounce两个Custom Hook,体会它是怎么像函数一样提取组件逻辑的。
自定义useMount:
功能:为在Dom渲染之后执行相关函数,即类似于class组件写法中的componentDidMount声明周期钩子的功能。
我们可以基于以下原理实现:如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。如果在函数组件中实现该功能,即代码如下所示:
//原代码:
useEffect(() => {
fetch(`${apiUrl}/users`).then(async response => {
if (response.ok) {
setUsers(await response.json())
}
})
}, [])
//利用useMount之后的代码:----------使用useMount
useMount(() => {
fetch(`${apiUrl}/users`).then(async response => {
if (response.ok) {
setUsers(await response.json())
}
})
}, [])
//在页面刚加载的时候执行一个函数,这个函数是通过callback传入的----创建useMount
export const useMount = (callback) => {
useEffect(() => {
callback()
}, [])
}
useDebounce----可以用来处理防抖值的Hook
首先,useDebounceFn和useDebounce都是一个用于添加防抖功能的hook,不同之处在于useDebounceFn给函数添加防抖,而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()
//debounce原理讲解:
//0s--------->1s --------->2s—-
//一定要理解:这三个函数都是同步操作,所以它们都是在0~1s 这个时间段内瞬间完成的;/log()#1// timeout#1
// log()#2//发现timeout#1!取消之,然后设置timeout#2//
log()#3//发现timeout#2!取消之,然后设置timeout#3
//
//所以,log()#3结束后,就只剩timeout#3在独自等待了
useDebounce例子:
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])
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
}
理解:CSS-in-JS不是指某一个具体的库,是指组织css代码的一种方式,代表库有styled-component和emotion。
1.传统css的缺陷
缺乏模块组织------传统的JS和CSS都没有模块的概念,后来在JS界陆续有了CommonJS和ECMAScript Module,CSS-in-JS可以用模块化的方式组织CSS,依托于JS的模块化方案。
例子:
//button1.ts---模块化
import styled from '@emoton/styled'
export const Button =style.button`
color: turquoise;
`
缺乏作用域-----------传统的css只有一个全局作用域,比如说一个class可以匹配全局的任意元素。随着项目成长CSS会变得越来越难以组织,最终导致失控。CSS-in-JS可以通过生成独特的选择符来实现作用域效果。例子:
.css-1c4ktv6 >*{
margin-top:0 ! important;
.margin-bottom: 0 ! important;
}
隐式依赖,让样式难以追踪;CSS-in-JS的方案就简单直接,易于追踪
没有变量------但是在CSS-in-JS中可以方便地控制空量
例子:
const container=style.div(props=>(
idisplay: 'flex ' ,
flexDirection: props.column && 'column'
}))|
CSS选择器与HTML元素耦合
.target .name h1{
color:red
}
body #container h1{
color:green
}
Document
我是啥颜色
Emotion介绍
Emotion是目前最受欢迎的CSS-in-JS库之一,它还对React做了很好的适应,可以方便地创建style component,也支持写行内样式:
/** @jsx jsx*/
import {jsx} from "@emotion/react"
reder{
This has a hotpink background.
}
这种写法比起React自带的style的写法功能更强大,比如可以处理级联,伪类等style处理不了的情况。