React:Hook
发布日期:2021-06-30 15:49:27
浏览次数:3
分类:技术文章
本文共 11244 字,大约阅读时间需要 37 分钟。
一、为什么要用React Hook
1. 官方介绍
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
2. 组件类的几个缺点
- 大型组件很难拆分和重构,也很难测试 ① 业务变得复杂之后,组件之间共享状态变得频繁,此时组件将变得非常难以理解和维护,复用状态逻辑更是难上加难 ② 如果使用redux和其中间件, 又将极大的加大项目的复杂度和体积 , 而且需要按照一套严格的标准去写组件和redux,才能保证一定的可维护和可扩展性
- 业务逻辑分散在组件的各个方法之中,导致重复逻辑或关联逻辑
- 组件类引入了复杂的编程模式,比如 render props 和高阶组件
3. 解决方案
- 提出思路 React 团队希望,组件不要变成复杂的容器,最好只是数据流的管道 ① 开发者根据需要,组合管道即可 ② 组件的最佳写法应该是函数,而不是类 React 早期版本也支持函数组件 ① 但是,这种写法有重大限制,必须是纯函数,不能包含状态 ② 也不支持生命周期方法,因此无法取代类
- React Hooks 诞生:React Hook 就是加强版函数组件,完全不使用"类",就能写出一个全功能的组件
二、什么是React Hook
1. 什么是React Hook
-
Hook
钩子 -
React Hooks 含义
① 组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来 ② React Hooks 就是那些钩子 -
使用React Hook
① 概念- React 默认提供了一些常用钩子
- 我们也可以封装自己的钩子
- 所有的钩子都是为函数引入外部功能,所以 React 约定,钩子一律使用use前缀命名,便于识别
- 你要使用 xxx 功能,钩子就命名为 usexxx
② 常用钩子
- useState()
- useContext()
- useReducer()
- useEffect()
-
案例实操
① useState基本使用// 1. 常规写法// import React from 'react'//// export default class Like001 extends React.Component { // state = { // age: 0// }//// render() { // return (//
//// );// }// }// 2. hook使用 ——> useStateimport React, { useState} from 'react'export default () => { // 2.1 使用钩子 const [age, setAge] = useState(0); const name = useState('KaiSarH') return (我今年{this.state.age}岁了!
// //老子是{ name}
我今年{ age}岁了!
② useEffect基本使用
// 1. 常规写法// import React from 'react'//// export default class Like001 extends React.Component { // state = { // count: 0// }//// componentDidMount() { // document.title = `点击了${this.state.count}次!`// }//// componentDidUpdate(prevProps, prevState, snapshot) { // document.title = `点击了${this.state.count}次!`// }//// render() { // return (//
//// );// }// }// 2. hook使用 ——> useState、useEffectimport React, { useState, useEffect} from 'react'export default () => { const [count, setCount] = useState(0); // useEffect——componentDidMount componentDidUpdate componentWillUnmount useEffect(() => { document.title = `点击了${ count}次` }); return (点击了{this.state.count}次!
// //点击了{ count}次!
③ todo简单案例
④ useEffect第二个参数运用- []相当于生命周期函数的:componentDidMount
- 有第二个参数:相对于生命周期函数:componentDidMount componentDidUpdate
- [count]:只监听count发生改变的时候,才会触发 componentDidUpdate
// // 1. 常规写法// import React from 'react'//// export default class Like003 extends React.Component { // state = { // count: 0,// name: 'KaiSarH'// }//// componentDidMount() { // document.title = `点击了${this.state.count}次!`// }//// componentDidUpdate(prevProps, prevState, snapshot) { // // document.title = `点击了${this.state.count}次!`// if (prevProps.count !== this.state.count) { // document.title = `点击了${this.state.count}次!`// }// }////// _dealCountClick() { // this.setState({ // count: this.state.count + 1// })// }//// _dealNameClick() { // // let name = this.state.name === 'King James' ? 'KaiSarH' : 'King James';// this.setState({ // name: 'King James'// })// }//// render() { // return (//
//// );// }// }// 2. hook使用 ——> useState、useEffectimport React, { useEffect, useState} from 'react'export default () => { const [count, setCount] = useState(0); const [name, setName] = useState('KaiSarH'); /* * 1. 如果不加第二个参数,默认是执行:componentDidMount componentDidUpdate * 2. 加了中括号,默认执行componentDidMount * 3. [状态]:只有状态发生改变时,才能触发componentDidUpdate * */ useEffect(() => { console.log('执行了·······') document.title = `点击了${ count}次` // return 中返回的相当于在componentWillUnMount return { } }, [count]) return (点击了{this.state.count}次!
//{this.state.name}
// // //姓名:{ name}
次数:{ count}
- return:相当于componentWillUnmount
// 1. 常规写法import React, { useState, useEffect} from 'react'import ReactDOM from 'react-dom'const AgeAPI = { age: 0, subscribe(callBack) { this.intervalId = setInterval(() => { console.log('定时器正在执行') this.age += 1; callBack(this.age); }, 1000); }, unsubscribe() { clearInterval(this.intervalId); }};// class Like004 extends React.Component { // state = { // age: 0// }//// componentDidMount() { // AgeAPI.subscribe((age) => { // this.setState({ // age// })// })// }//// componentWillUnmount() { // AgeAPI.unsubscribe();// }//// render() { // return (//
//// );// }// }//// export default Like004;const Like004 = () => { const [age, setAge] = useState(0); useEffect(() => { AgeAPI.subscribe((currentAge) => { setAge(currentAge) }) // 处理副作用代码,相当于在componentWillUnmount return () => { AgeAPI.unsubscribe(); } }, []) return (我是树妖,今年{this.state.age}岁了!
// //我是树妖{ age}
⑤ hook中使用网络请求
- 基本使用
import React, { useEffect, useState} from 'react'import ajax from "../http";const Like005 = () => { const [data, setDate] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { const response = await ajax('http://demo.itlike.com/web/xlmc/api/homeApi/categoriesdetail/lk001?itlike=87224866875667849947') setDate(response.data.data); setLoading(false); })() }, []) return (
{ loading ?)}export default Like005;正在拼命加载中: data.cate[0].name} - 自己包装一个钩子
import React, { useEffect, useState} from 'react'import ajax from "../http";const useAjax = (url) => { const [data, setDate] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { const response = await ajax(url) setDate(response.data.data); setLoading(false); })() }, []) return { data, loading}}const Like005 = () => { const { data, loading} = useAjax('http://demo.itlike.com/web/xlmc/api/homeApi/categoriesdetail/lk001?itlike=87224866875667849947'); return (
{ loading ?)}export default Like005;正在拼命加载中: data.cate[0].name}
⑥ Hook 使用规则
- 只在最顶层使用 Hook
- 只在 React 函数中调用 Hook
⑦ Hook中处理副作用操作
⑧ 性能优化:对比文档前后,如果没有变化就不进行渲染-
import React from 'react'import Other from './other'// export default class Like008 extends React.Componentexport default class Like008 extends React.PureComponent{ state = { age: 0 }; /* componentDidMount() { setInterval(()=>{ this.setState({ // age: this.state.age + 1 age: 100 }) }, 1000); } */ componentDidMount() { setInterval(()=>{ this.setState({ age: this.state.age + 1 }) }, 1000); } render() { console.log('render被调用了~~~~'); return (
{ this.state.age} -
React.memo
import React from 'react'const Other = ({ otherName})=>{ console.log('other组件中的render被调用了'); return (
我叫: { otherName}
)};// export default Otherexport default React.memo(Other);
⑨ useCallback使用
-
示例
const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b],);
-
实操
① 第二个参数决定了是否允许第一个参数执行 ② 二个参数发生变化则允许执行,否则则不允许执行 ③ 第一个参数第一次会执行一次,之后才会判断第二个参数是否发生变化然后再执行/* useCallback 网址: https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b],);- 第二个参数b决定了是否允许第一个参数执行- 第一个参数第一次会执行, 之后会根据第二个参数的变化决定是否执行*/import React, { useState, useCallback} from 'react'const Like009 = ()=>{ const [age, setAge] = useState(1); const [weight, setWeight] = useState(50); function clickHandler() { setAge(age + 1); } return (
年龄: {
age} 岁体重: {
weight}千克 { /* */}
⑩ usereducer
[网址](https://zh-hans.reactjs.org/docs/hooks-reference.html#usereducer)
import React, { useState, useReducer} from 'react'const initialState = { count: 0};function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1}; case "decrement": return { count: state.count - 1} }}function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return (
计算结果: { state.count})}export default Counter;⑪ usecontext
import React, { useContext} from 'react'const themes = { dark: { width: 100, height: 40, borderRadius: 10, border: 'none', color: 'green', backgroundColor: 'orange' }};const ThemeContext = React.createContext();function App() { return (
转载地址:https://kaisarh.blog.csdn.net/article/details/111476948 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月18日 14时11分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
数字货币的投资正确之路
2019-05-01
委员会怎么验证比特币真伪
2019-05-01
迅雷陷入窘迫,但是无可替代
2019-05-01
PHP之 使用PHPMailer插件实现邮件发送功能
2021-07-04
Linux之 关于VM虚拟机网卡的设置
2021-07-04
《增长黑客》(肖恩·艾利斯)学习笔记——第一部分 方法
2021-07-04
《增长黑客》(肖恩·艾利斯)学习笔记——第二部分 实战
2021-07-04
冒泡排序及优化(JAVA算法)
2021-07-04
Mysql学习笔记(9):数据类型和约束
2019-05-01
Mysql学习笔记(10):事务、视图
2019-05-01
JDBC学习笔记(1):JDBC概述
2019-05-01
JAVA进阶学习笔记(8):反射
2019-05-01
原始值与引用值(ES6学习笔记)
2019-05-01
python使用HTMLTestRunner查看运行函数
2019-05-01
linux系统安装mysql数据库
2019-05-01