React Hooks 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

前言

本篇主要以讲几个常用的api为主。

1.useState

这个例子用来显示一个计数器。当你点击按钮,计数器的值就会增加,现在我们的写法如下,

class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
} render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}

这是我们所熟悉的写法,替换成useState后

import React, { useState } from 'react';

function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
  • 1.首先通过在函数组件里调用useState()来给组件添加一些内部 state,(React 会在重复渲染时保留这个 state)。
  • 2.useState()可以传入一个参数,传入的参数就是初始的state,在上面例子当中,0就是初始值。【这个初始 state 参数只有在第一次渲染的会被用到。】
  • 3.useState() 会返回一对值:当前状态和一个让你更新它的函数(你可以在事件处理函数中或其他一些地方调用这个函数,它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。)
  • 4.可以通过useState声明多个state变量,如下
function ExampleWithManyStates() {
// 声明多个 state 变量!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}

2.useEffect

useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

依然是先上例子

class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
} componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
} componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
} render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
import React, { useState, useEffect } from 'react';

function Example() {
const [count, setCount] = useState(0); // 相当于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
document.title = `You clicked ${this.state.count} times`;
}); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
  • 1.默认情况下,React 会在每次渲染后调用副作用函数 —— 包括第一次渲染的时候。

  • 2.副作用函数还可以通过返回一个函数来指定如何“清除”副作用。它的执行顺序是,每次页面更新前,先执行return的函数,然后在执行useEffect里面的内容。

import React, { useState, useEffect } from 'react';

function Example() {

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

  useEffect(() => {
console.log(`You clicked ${count} times`);
return () => {
console.log('每次页面更新前,我会先被执行');
}
}); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
  • 3.跟 useState 一样,你可以在组件中多次使用 useEffect,因此通过使用 Hook,你可以把组件内相关的副作用组织在一起(例如创建订阅及取消订阅),而不要把它们拆分到不同的生命周期函数里。
  • 4.useEffect还可以传入第二个参数,指定当某个值发生变化的时候,才触发副作用.
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
  • 5.如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。

3.useReducer

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)

// reducer.js
export const initialState = {count: 0}; export default (state, action) => {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
} // Counter.js
import React, { useReducer } from 'react';
import reducer, { initalState } from './reducer.js'; function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</div>
);
}

4.useContext

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

具体使用查看这篇文章。

React Hooks新特性学习随笔的更多相关文章

  1. 使用React Hooks新特性useReducer、useContext替代传统Redux高阶组件案例

    当我们使用redux进行数据管理的时候,一般都是在根组件通过Provider的方式引入store,然后在每个子组件中,通过connect的方式使用高阶组件进行连接,这样造成的一个问题是,大量的高阶组件 ...

  2. ES7/8新特性学习随笔

    随着每年EcmaScript都会为js带来一些新特性,带来更多美化的编程体验,今天就走进一下es2016/2017所带来的新特性 ES7新特性 includes() 指数操作符 ES8新特性 asyn ...

  3. JavaScript ES6 数组新方法 学习随笔

    JavaScript ES6 数组新方法 学习随笔 新建数组 var arr = [1, 2, 2, 3, 4] includes 方法 includes 查找数组有无该参数 有返回true var ...

  4. Java8 新特性学习 Lambda表达式 和 Stream 用法案例

    Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...

  5. java8 新特性学习笔记

    Java8新特性 学习笔记 1主要内容 Lambda 表达式 函数式接口 方法引用与构造器引用 Stream API 接口中的默认方法与静态方法 新时间日期 API 其他新特性 2 简洁 速度更快 修 ...

  6. QQ音乐:React v16 新特性实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由QQ音乐技术团队发表于云+社区专栏 自从去年9月份 React 团队发布了 v16.0 版本开始,到18年3月刚发布的 v16.3 版 ...

  7. java8新特性学习1

    java8增加了不少新特性,下面就一些常见的新特性进行学习... 1.接口中的方法 2.函数式接口 3.Lambda表达式 4.java8内置的四大核心函数式接口 5.方法引用和构造器引用 6.Str ...

  8. java8新特性学习:函数式接口

    本文概要 什么是函数式接口? 如何定义函数式接口? 常用的函数式接口 函数式接口语法注意事项 总结 1. 什么是函数式接口? 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口 ...

  9. java8新特性学习:stream与lambda

    Streams api 对 Stream 的使用就是实现一个 filter-map-reduce 过程,产生一个最终结果,或者导致一个副作用(side effect). 流的操作类型分为两种: Int ...

随机推荐

  1. 洛谷P1280 尼克的任务

    这个DP气死我了.....写的时候脑子比较迟钝于是爆0了好几次,最后还是我旁边的AKIOI巨佬告诉我解法才会做. 我一开始设计的状态是f[i]表示i时刻正在休息,从1到i的最长休息时间. 然后经历了各 ...

  2. 界面编程之QT的事件20180727

    /*******************************************************************************************/ 一.事件 1 ...

  3. maven的三种工程pom、jar、war的区别

    转: maven的三种工程pom.jar.war的区别 2018年09月03日 10:02:53 houjx3 阅读数:2918更多 个人分类: maven   1.pom工程:用在父级工程或聚合工程 ...

  4. mybatis的面试一对一,一对多,多对多的mapper.xml配置

    使用springboot完成一对一,一对多: https://blog.csdn.net/KingBoyWorld/article/details/78966789 传统的mapper文件中的一对一, ...

  5. DP(动态规划)

    http://www.hawstein.com/posts/dp-novice-to-advanced.html https://www.topcoder.com/community/data-sci ...

  6. linux中eth0原何变成了eth1

    Linux的网卡由eth0变成了eth1,如何修复使用wmware安装了linux,安装成功后,使用的网卡是eth0,没有eth1.但是用过一段时间后,不知道为什么eth0无法使用,系统却自动生成了e ...

  7. 关于爬取数据保存到json文件,中文是unicode解决方式

    流程: 爬取的数据处理为列表,包含字典.里面包含中文, 经过json.dumps,保存到json文件中, 发现里面的中文显示未\ue768这样子 查阅资料发现,json.dumps 有一个参数.ens ...

  8. 蓝桥杯 大臣的旅费_树的最长度_两次DFS

    #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> ...

  9. PHP-PSR-[0-4]代码规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

  10. html5 canvas 奇怪的形状垂直渐变

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...