本文已参与「新人创作礼」活动,一起开启掘金创作之路
React中类组件和函数式组件的区别
- 语法上: 类组件需要继承React.component,创建render函数,返回React元素,而函数式组件接受一个props参数,直接返回React元素
- 状态管理上: 类组件可是使用state来管理组件内部的状态,而函数式组件没有状态管理,没有this,没有state,也没有生命周期
- 调用方式上: 函数式组件可以直接调用,返回一个react元素,而类组件是创建实例然后调用实例的render方法,返回react元素
hook的作用
- hook使开发者能在函数式组件中使用state,以及其他react特性
- useEffect使开发者能在函数式组件中使用react生命周期特性
- hook能简化逻辑复用,更好的复用代码,
- 可以很容易的拆分大型组件,使代码更容易理解
常见的hook函数
- useEffect
- useState
- useCallback
- useMemo
- useReducer
- useContext
- useRef
React 自定义hook
当项目中需要实现某些特定功能,而官方提供的hook不足以满足需求的时候我们可以自定义hook
自定义hook需要遵循的 规则:
- 自定义hook本质上是一个函数,命名以use开头,
- 自定义hook内部能正常的使用useState,useEffect或其他hook
- 自定义返回结果
- 在不同组件中使用hook不会共享state
- 每次调用hook都能获取独立的state
实现一个自定义hook,监听窗口变化
const useWindowSize = () > {
const [window,setWindow] = useState({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
})
useEffect(() => {
window.addEventListener("resize",() => {
setWindow({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
})
})
// 组件销毁时移除监听
return () => {
window.removeEventListener('resize',() => {
setWindow({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
})
})
}
},[])
return window
}
尝试一下重写useState
let _state
const myuseState = (initialValue) => {
if(_state == null) {
_state = initialValue
}else{
_state = _state
}
const setState = (value) => {
_state = value;
render()
}
return [_state,setState]
}
这种实现方式state只能存储一个值,当多次调用state时,会造成state之间的冲突
为了存储多个值,我们可以用数组来存储state
let _state = []
let index = 0
const myuseState = (initialValue) => {
const currentIndex = index
if(_state[currentIndex] == null) {
_state[currentIndex] = initialValue
}else{
_state[currentIndex] = _state
}
const setState = (value) => {
_state[currentIndex] = value;
render()
}
index++
return [_state[currentIndex],setState]
}
useState在使用时规定只能写在函数最外层,不能写在条件语句中,就是因为useState的值是按一定顺序排列的,如果顺序错乱,取值会报错