我是靠谱客的博主 长情棒棒糖,这篇文章主要介绍 react随笔之hooks(一),现在分享给大家,希望可以做个参考。

Hooks使用条件

目前用create-react-app脚手架创建的项目,react和react-dom版本为^16.7.0,该版本还未支持hooks的使用,未升级使用会报错误:TypeError: Object(...) is not a function。

升级react的版本很简单,在该项目目录下执行如下语句即可。

复制代码
1
yarn add react@next react-dom@next

完成后可查看package.json文件是否升级成功,该文章代码是基于react react-dom ^16.8.0-alpha.1版本运行的。

Hooks是写在React function里面的,与之前的class不同,就像官网的例子里一样。我们可以这样

复制代码
1
2
3
4
const Example = (props) => { // You can use Hooks here! return <div />; }

或者这样

复制代码
1
2
3
4
function Example(props) { // You can use Hooks here! return <div />; }

又或者直接

复制代码
1
2
3
4
export default (props) => { // You can use Hooks here! return <div />; }

总之

  • 只在 React Functions 调用 Hooks
  • 只在顶层调用Hook,不能在循环,条件或嵌套函数中调用Hook

useState

首先需要import一下useState

复制代码
1
import React, { useState } from "react";

然后我们就可以在function里面使用了,以count为例,方法如下

复制代码
1
const [count, setCount] = useState(0);

count是state,0是count的初始值,setCount是设置count的一个函数(函数名不一定要是setXxx,也可以如sCount等,但不建议这么做),setCount()等效于?

复制代码
1
2
3
4
5
setCount = (count) => { this.setState({ count }) }

useState只能在顶层调用,不能在循环,条件或嵌套函数中调用,因为useSate是基于数组的实现的,而他们的下标是根据useState出现顺序决定的,假设判断语句中存在useState,当判断不成立时(即不执行判断包裹的代码时),useState会因为下标错乱而出错。想了解更多可看React hooks: not magic, just arrays (需科学上网)或官网的Rules of Hooks

具体使用如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
import React, { useState } from 'react'; function Cunter() { const [count, setCount] = useState(0); return ( <div className="count-box"> <h1 className="title">点了{count}次</h1> <button onClick={() => {setCount(count + 1);}}>Click Me!</button> </div> ); } export default Cunter;

useEffect

useEffect结合了componentWillMount、componentDidMount和componentWillUnmount的特性。useEffect可以传入两个参数,第一个是必选参数,为function类型,是effect执行的内容,第二为可选参数,为数组类型,是判断是否执行该effect,若第二参数的数值发生变化,则执行。

复制代码
1
2
3
4
useEffect(()=>{ console.log('current count:'+count) })

?组件加载时、state变化时,都会执行console.log

复制代码
1
2
3
4
5
useEffect(()=>{ console.log('first effect count:'+count)//new count return function cleanup(){console.log('first effect return count:'+count)}//old count })

?组件加载时执行第一个console.log,state变化时,会先执行return的cleanup函数,打印上一次运行时的count,再执行第一个console.log。
注意!这里上一个运行时的意思是该effect上一次执行时的state,并非是上一个state,这么说有点绕,看一下这个例子?

复制代码
1
2
3
4
5
useEffect(()=>{ console.log('third effect count:'+count) return function cleanup(){console.log('third effect return count:'+count)} },[count>4?1:0])

?假设你点击了8次,当你点第五次时,此时第二参数的内容从0变成了1,所以执行了该effect,打印了

third effect return count:0
third effect count:5

之后再也不执行该effect,直到将这个组件卸载时,才会执行该effect的cleanup函数,但打印的并不是想象中的 8 ,而是

third effect return count:5

既该effect的上一次运行时的state。


因为该特性,所以并不推荐第二参数传递[]来模拟componentDidMount 和componentWillUnmount,引用官网的原话

While passing [] is closer to the familiar componentDidMount and componentWillUnmount mental model, we suggest not making it a habit because it often leads to bugs, as discussed above. Don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.

完整代码?

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Count.jsx import React, { useState, useEffect } from "react"; function Cunter() { const [count, setCount] = useState(0); useEffect(()=>{ console.log('first effect count:'+count) return function cleanup(){console.log('first effect return cleanup')} },[]) useEffect(()=>{ console.log('second effect, current count:'+count)//new count return function cleanup(){console.log('second effect return count:'+count)}//old count }) useEffect(()=>{ console.log('third effect count:'+count) return function cleanup(){console.log('third effect return count:'+count)} },[count>4?1:0]) return ( <div className="count-box"> <h1 className="title">点了{count}次</h1> <button onClick={() => {setCount(count + 1);}}>Click Me!</button> </div> ); } export default Cunter;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//App.jsx import React, { Component } from "react"; import Cunter from "./Cunter"; class App extends Component { constructor(props) { super(props); this.state = { show: true }; } render() { return ( <div> {this.state.show ? <Cunter /> : <p>cleanup</p>} <br/> <button onClick={() => {this.setState({ show: false })}}>cleanup</button> </div> ); } } export default App;

最后

以上就是长情棒棒糖最近收集整理的关于 react随笔之hooks(一)的全部内容,更多相关内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(96)

评论列表共有 0 条评论

立即
投稿
返回
顶部