Hook是 React16.8 的新增特性, 它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
以此来提高代码的复用性,
关于代码的复用的解决方案 从最开始的 Mixin
到 HOC
到 Render Prop
,再到至今的 Custom Hook
。
Mixin在使用上存在一些弊端,
复用的代码的相关依赖都是隐式的,不好追踪的,结果也是不好预测的,并且存在命名冲突覆盖的问题,后面被React不推荐使用
var sentryMixin = {
this.startTime = null
componentDidMount() {
this.startTime = new Date()
},
componentWillUnmount() {
const endTime = new Date()
console.log(endTime - this.startTime)
}
}
var UserPage = React.createClass({
mixins: [sentryMixin],
render() {
return <div>UserPage Component</div>
}
})
HOC 本质上是一个函数,接收Component 为参数, 返回一个新的组件
组件可分为容器组件(container)和展示组件(component)
容器组件保存状态和事件,展示组件根据父级传入的状态和事件用来渲染
const withSentry = (Component) => {
class HOCComponent extends React.Component {
componentDidMount() {
this.startTime = new Date()
}
componentWillUnmount() {
const endTime = new Date()
console.log(endTime - startTime)
}
render() {
return <Component />
}
}
return <HOCComponent />
}
class UserPage extends React.Component {
render() {
return <div>UserPage</div>
}
}
withSentry(UserPage)
至今的就是 React Hook了
函数组件可以实现代码复用, 但是函数没有状态,也无法复用。
hook的出现就是为了解决复用函数组件时不能复用状态的问题,hook的核心是闭包,
hook只能在函数的顶层使用,不能在判断、循环语句,jsx中使用
-
useState
最基础的hook,状态生成器,函数接收一个参数为默认状态值。
返回一个数组
[state, setState]
, 既状态值和修改状态的方法例如:
const [foo, setFoo] = useState('hello') console.log(foo) // hello setFoo('world') console.log(foo) // world
-
userEffect
接收两个参数 effectCallback 和 dept?
effectCallback为 当 dept 发生变化时的回调函数,当组件卸载时会执行
effectCallback()()
,可利用此特性移除一些副作用函数,比如监听事件,定时器dept 为需要监听的值,这个值的类型为数组或
undefined
,当为undefined时,则每次函数执行都会调用,当为[]
则表示不监听任何值,只会执行一次,利用此特性注意dept的值不能为复杂类型的普通值,可以是简单类型的值或者经过缓存的状态值,因为,复杂类型的值和闭包中保存的值来比较,由于内存地址不同是不等的,
此hook没有返回值
示例
const Counter = () => { useEffect(() => { const timer = setInterval(() => { console.log('hi!') },1000) return () => clearInterval(timer) },[]) }
加上状态值
const Counter = () => { const [count, setCount] = useState(0) useEffect(() => { const timer = setInterval(() => { console.log(count) setCount(count + 1) },1000) return () => clearInterval(timer) },[]) }