前言
react的hooks功能是在16.8的版本里面投入使用的一个全新的特性,可以说它是为了把原来的class组件很多麻烦事都给你干了,只要可以很好的理解它的几个常用的API,这个新的特性,将会非常的好用。
唯一的一个问题就是——可以理解这些API
下面我就把我这段时间学习Hooks的一些理解分享给大家,如果有什么理解错误的地方,欢迎大家评论区指正。
State / setState 和 useState
在class组件里面,我们想给组件附上一个state状态值,同时想要通过方法改变这个state的状态值,一般来说会用下面这种形式来操作。
class Order extends Component {
constructor(props) {
super(props)
this.state = { date: 66 }
}
changeDate = () => {
this.setState((state) => {
return {
date: state.date + 1,
}
})
}
render() {
return (
<div className="box">
<span>{this.state.date}</span>
<button onClick={this.changeDate}>CHANGE</button>
</div>
)
}
}
这里有几个必须要注意的,就是this,state必须跟一个对象或者是null,可以说写起来是比较麻烦的,那么在Hooks的函数组件里面可以怎么写呢。
function Order() {
const [date, setdate] = useState(66)
const changeDate = () => {
setdate(date + 1)
}
return (
<div className="box">
<span>{date}</span>
<button onClick={changeDate}>CHANGE</button>
</div>
)
}
我还不会制作gif图,大概情况样式就是这样,大家将就一下…
可以说这第一步就比原来的class组件要来的快捷了很多,因为React里面有规定,就是不要直接的去操作state,所以其实useState是创建了一个新的state的值来进行操作,(这里有点底层我也还不是很懂…),同时useState传递的参数可以是任何形式的数据
数组,字符串,数字,对象都是没问题的。
const [date, setdate] = useState({
num:1
})
const [state, setstate] = useState([1,2,3])
对副作用的处理(useEffect)
在class组件里,如果想要想要进行一些副作用的处理,例如发送http请求数据,或者给一些DOM绑定监听事件之类时候,一般来说会把它放在生命周期钩子里的 compnentDisMount 里面去进行。
componentDidMount(){
Axios.get('/baidu.json')
.then((res)=>{})
}
或者是给DOM绑定监听事件
constructor(props) {
super(props)
this.state = { date: 66 }
this.Dom = createRef()
}
componentDidMount() {
this.Dom.current.addEventListener('click', this.changeDate)
}
changeDate = () => {
this.setState((state) => {
return {
date: state.date + 1,
}
})
}
render() {
return (
<div className="box">
<span>{this.state.date}</span>
<button ref={this.Dom}>CHANGE</button>
</div>
)
}
这里为了防止在组件销毁的时候监听事件不会跟着销毁而造成内存泄露的情况,还需要在组件销毁的时候对监听事件进行解绑,一般这种情况会把它放在生命周期钩子 componentWillUnmount里面来进行。
componentWillMount(){
this.Dom.current.removeEventListener('click', this.changeDate)
}
同样的也是写起来非常的麻烦,那么在useEffect里面可以怎么处理呢
function Order() {
const [date, setdate] = useState(1)
const Dom = useRef()
useEffect(() => {
Dom.current.addEventListener('click', changeDate)
return () => {
Dom.current.removeEventListener('click', changeDate)
}
})
const changeDate = () => {
setdate(date + 1)
}
return (
<div className="box">
<span>{date}</span>
<button ref={Dom}>CHANGE</button>
</div>
)
}
useEffect它会有一个回掉函数,作用就相当于是生命周期钩子的componentWillUnmount,它会在组件将要被销毁的时候调用这个回掉函数,这样就可以对绑定的监听事件进行一个解绑的动作,可以说是非常的快捷。
同时useEffect还支持传入第二个参数,一般是一个数组,这个数组里面的值,会作为useEffect执行的一个依赖项,如果说这个数组里面的值不改变的时候,那么这个钩子就不会执行了。
例如,将Dom传入给他作为依赖项,因为Dom是一个不会改变的量了,这时候我们的useEffect只会渲染一次,并且不管你点击几次都只会执行一次。
const Dom = useRef()
useEffect(() => {
Dom.current.addEventListener('click', changeDate)
console.log(666)
return () => {
Dom.current.removeEventListener('click', changeDate)
}
}, [Dom])
但是如果在没有依赖项的情况下,useEffect函数会在每次点击之后都会被执行一次。
注意事项!!
这里我要说一点我自己在学习react的过程中,踩的一些坑。
有一点需要注意的就是react的组件在传入新的props的时候,会触发重渲染,但是由于虚拟DOM的关系,并不会触发重绘!!
重点来了:usestate的state值,在最初通过参数传进去的时候,想要改变它,只能通过setstate的方式来改变,除非触发了重绘,否则,usestate传参怎么改变,state的值都是不会改变的!!!
例如下面的这个例子
const Demo = (props) => {
const [state,setstate] = usestate(props)
return <div>{state}</div>
}
相信这种情况非常的常见,通过把传递进来的props作为state的值,但是,在props的值改变的时候,state的值并不会跟着改变!!
那么这种情况要怎么办的??
这种情况最优的一个解法依然是使用useEffect来解决这个问题
只需要加多一句话,就可以了。
useEffect(()=>{
setState(props)
})
就是这么简单,当时这个问题困扰了我挺久的,这里我就分享一下,当然,大佬们请绕道,我只是一个小菜鸡。
最后
因为篇幅有限,我就先更新这两个最常用的Hooks的API先,之后我还会更新新的我对于react hooks的一些理解的文章。
如果你觉得我的文章对你有所帮助de话,麻烦点个赞呀!!!