我是靠谱客的博主 长情棒棒糖,最近开发中收集的这篇文章主要介绍 react随笔之hooks(一),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Hooks使用条件

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

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

yarn add react@next react-dom@next

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

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

const Example = (props) => {
// You can use Hooks here!
return <div />;
}

或者这样

function Example(props) {
// You can use Hooks here!
return <div />;
}

又或者直接

export default (props) => {
// You can use Hooks here!
return <div />;
}

总之

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

useState

首先需要import一下useState

import React, { useState } from "react";

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

const [count, setCount] = useState(0);

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

setCount = (count) => {
this.setState({
count
})
}

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

具体使用如下:

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,若第二参数的数值发生变化,则执行。


useEffect(()=>{
console.log('current count:'+count)
})

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


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,这么说有点绕,看一下这个例子?


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.

完整代码?

//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;

//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(一)的全部内容,希望文章能够帮你解决 react随笔之hooks(一)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部