目录

  • 1 为什么使用 React Hooks
  • 2 详解 useState
  • 3 useEffect的使用
    • 3.1useEffect代替常用的生命周期函数
    • 3.2 实现类似componentWillUnmount(组件将要被卸载时执行)
  • 4 useContext的使用
  • 5 useReducer的使用
    • 5.1 useReducer时实现reducer
    • 5.2 useReducer useContext实现redux的状态管理和状态共享
  • 6. useMemo
  • 7. useRef
  • 8. 自定义Hooks函数

1 为什么使用 React Hooks

对于一个新玩意(这也不算新玩意了)的使用肯定是有他的原因的撒,我们先来个简单例子看看,现在我们做过超级超级简单的例子:点击按钮数字增加1
先用我们原来的做法(用class的方式定义的组件)

import React, { Component } from 'react'class Increased extends Component {constructor (props) {super (props) this.state={count:0}}render() {return (<div><p>总数:{this.state.count}</p><button onClick={this.add.bind(this)}>增加</button></div>)}add() {this.setState({count:this.state.count+1})}
}
export default Increased

咋们在来看看使用React Hooks做的

import React,{useState } from 'react'const IncreasedHooks = () => {const [ count , setCount ] =useState(0)//数组解构return (<div><p>总数:{count}</p><button onClick={()=>setCount(count+1)}>增加</button></div>)
}
export default IncreasedHooks

下面是效果:

2 详解 useState

useState是react自带的一个hook函数,它的作用是用来声明状态变量。useState这个函数接收的参数是状态的初始值,它返回一个数组,这个数组的第0位是当前的状态值第1位是可以改变状态值的方法函数

  1. 如何声明 根据上面的代码就知道啦
 const [ count , setCount ] =useState(0)//数组解构
  1. 如何读取
    因为返回的是个数组,按照取数组的元素的方式取就行了啦,读取是很简单的。只要使用{count}就可以,因为这时候的count就是JS里的一个变量,想在JSX中使用,值用加上{}就可以。
    建议使用解构的方式,简单快速,什么? 你不会解构? 那你戳这个吧解构赋值这些些你必须知道
 <p>总数:{count}</p>
  1. 使用 改变state 我们就要使用返回的数组中的第二个值啦
    <button onClick={()=>setCount(count+1)}>增加</button>

3 useEffect的使用

3.1useEffect代替常用的生命周期函数

useEffect 可以用来代替我们常用的声明周期函数 ,那我们一般什么时候使用生命周期函数呢,当然是我们在是做"副作用"的业务处理 代替了componentDidMountcomponentDidUpdate。分别在组件第一次渲染后在浏览器控制台打印出计数器结果和在每次计数器状态发生变化后打印出结

使用useEffect时候有两点需要注意的

  • React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)。

  • useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而componentDidMonutcomponentDidUpdate中的代码都是同步执行的。个人认为这个有好处也有坏处吧,比如我们要根据页面的大小,然后绘制当前弹出窗口的大小,如果时异步的就不好操作了。

const IncreasedHooks = () => {const [ count , setCount ] =useState(0)useEffect(()=>{console.log(`useEffect=>You clicked ${count} times`)
})
//解决生命周期函数 代替了componentDidMount和componentDidUpdate。分别在组件第一次渲染后在浏览器控制台打印出计数器结果和在每次计数器状态发生变化后打印出结return (<div><div>使用React Hooks</div><p>总数:{count}</p><button onClick={()=>setCount(count+1)}>增加</button></div>  )
}

3.2 实现类似componentWillUnmount(组件将要被卸载时执行)

使用路由实现组件的解绑,需要用到useEffect函数里面返回一个函数的形式,代替解绑生命周期函数 componentWillUnmount 组件将要被卸载时执行

const Index = () => {useEffect(()=>{console.log('useEffect=>老弟你来了!Index页面')return ()=>{console.log('老弟,你走了!Index页面')}//返回一个函数的形式,代替解绑生命周期函数 componentWillUnmount 组件将要被卸载时执行},[])return <div>加油,程序员</div>
}
const List = () =>{return (<ul><li>你好</li><li>我好</li><li>他好</li></ul>)
}const IncreasedHooks = () => {return (<div>   <Router><ul><li><Link to = "/">首页 </Link></li><li><Link to = "/list/">列表页 </Link></li></ul><Route path ="/" exact component={Index}></Route><Route path ="/list/" component={List}></Route></Router></div>)
}


其实这个主要是使用的useEffect的第二个参数,上面的程序中,不是用第二个参数的时候.每次状态发生变化,useEffect都进行了解绑。真正实现主要是第二个人函数加了空数组.useEffect的第二个参数,它是一个数组,数组中可以写入很多状态对应的变量,意思是当状态值发生变化时,我们才进行解绑。但是当传空数组[]时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount的生命周期函数。

我的理解是:第二个参数是实现解绑条件

例如:给计数器也加上解绑:只需要在返回的数组中写入记录计数的状态值count 变量

const IncreasedHooks = () => {const [ count , setCount ] =useState(0)//数组解构useEffect(()=>{console.log(`useEffect=>You clicked ${count} times`)return ()=>{console.log('====================')}},[count])return (<div><p>总数:{count}</p><button onClick={()=>setCount(count+1)}>增加</button></div>)
}

4 useContext的使用

useContext主要是用来实现父子组件之间的传值 如下代码实现

import React,{useState ,useContext, createContext } from 'react'
const CountContext = createContext()// 定义子组件
const Coounter = () =>{//子组件一句话就可以得到父组件传递过来的count
const count = useContext(CountContext)
return (<h2>{count}</h2>)
}// 父组件
const IncreasedHooks2= () => {const [ count , setCount ] =useState(0)return (<div><div>使用React Hooks</div><p>总数:{count}</p><button onClick={()=>setCount(count+1)}>增加</button>{/* 父组件向组件提供值 */}<CountContext.Provider value={count} ><Coounter/></CountContext.Provider></div>)
}
export default IncreasedHooks2

5 useReducer的使用

5.1 useReducer时实现reducer

useContextuseReducer 合作可以完成类似的Redux库的操作,useReducer 可以让代码具有更好的可读性和可维护性,它类似于Redux中的reducer,reducer这个函数接收两个参数,一个是状态,一个用来控制业务逻辑的判断参数
一个简单reducer的例子来理解什么是reducer

function countReducer(state, action) {switch(action.type) {case 'add':return state + 1;   case 'sub':return state - 1;default: return state;}
}

使用useReducer

import React, { useReducer } from 'react';const IncreasedHooks2 = () => {const [count, dispatch] = useReducer((state, action) => {switch (action) {case 'add':return state + 1case 'sub':return state - 1default:return state}}, 0)return (<div><h2>现在的分数是{count}</h2><button onClick={() => dispatch('add')}>Increment</button><button onClick={() => dispatch('sub')}>Decrement</button></div>)}export default IncreasedHooks2

5.2 useReducer useContext实现redux的状态管理和状态共享

实现状态全局化并能统一管理,统一个事件的派发

案例:点击按钮切换对应的字体颜色

//父组件
import React from 'react';
import Buttons from './Buttons';
import ShowArea from './ShowArea'
import { Color } from './Color';   //引入Color组件
const ChangeColor = () => {return ( <div><Color><Buttons /><ShowArea /></Color></div> )
}export default ChangeColor//字体展示组件
import React,{useContext} from 'react'
import { ColorContext } from './Color';const ShowArea = () => {// 获取colorconst {color} = useContext(ColorContext)return ( <div><div style={{color:color}}>字体颜色为{color}</div></div>)
}export default ShowArea//按钮组件
import React ,{useContext} from 'react';
import {ColorContext,UPDATE_COLOR} from './Color'
const Buttons = () => {// 获取共享的dispatchconst {dispatch} = useContext(ColorContext)return ( <div>{/* 使用dispatch派发一个action */}<button onClick= {()=> {dispatch({type:UPDATE_COLOR,color:"red"})}}>红色</button><button onClick= {()=> {dispatch({type:UPDATE_COLOR,color:"yellow"})}}>黄色</button>
</div>)
}export default Buttons//状态管理
import React,{createContext ,useReducer } from 'react'
export const ColorContext = createContext()
export const UPDATE_COLOR = "UPDATE_COLOR"
// 定义reducer
const reducer = (state, action) => {switch (action.type) {case UPDATE_COLOR:return action.colordefault:return state}
}
// 颜色共享
export  const Color = props => {// 使用reducer
const [color, dispatch] = useReducer(reducer,'red')return ( <div>{/* 将color和dispatch共享出去 */}<ColorContext.Provider value={{color,dispatch}}>{props.children}</ColorContext.Provider></div>);
}

结果

6. useMemo

useMemo主要用来解决使用React hooks产生的无用渲染的性能问题,函数型组件没有shouldCompnentUpdate(组件更新前触发),我们就没有办法通过组件前的条件来决定组件是否更新.
且在函数组件中,也不再区分mountupdate两个状态,这意味着函数组件的每一次调用都会执行内部的所有逻辑,就带来了非常大的性能损耗。useMemouseCallback都是解决上述性能问题的


import React , {useState,useMemo} from 'react';function ComeHere(){const [he, setHe] = useState('他在等着')const [me, setMe] = useState('我在等着')return (<><button onClick={()=>{setHe(new Date().getTime())}}>他</button><button onClick={()=>{setMe(new Date().getTime()+',我走来了')}}>我</button><ChildComponent name={he}>{me}</ChildComponent></>)
}function ChildComponent({name,children}){function changeHe(name){console.log('她来了,她来了。他向我们走来了')return name+',他向我们走来了'}
//为了解决当我们点击"我"按钮时,"他"对应的changeHe方法不能执行,只有在点击他按钮时才能执行。才能减少子组件的多次没有用的重新渲染
//其实只要使用useMemo,然后给她传递第二个参数,参数匹配成功,才会执行。const actionHe = useMemo(()=>changeHe(name),[name]) return (<><div>{actionHe }</div><div>{children}</div></>)
}

7. useRef

  • useRef获取React JSX中的DOM元素,获取后你就可以控制DOM的任何东西了。但是一般不建议这样来作,React界面的变化可以通过状态来控制。

  • useRef来保存变量,这个在工作中也很少能用到,我们有了useContext这样的保存其实意义不大

import React, { useRef} from 'react';
function Example(){//声明一个input的elementconst inputEl = useRef(null)const onButtonClick=()=>{ inputEl.current.value="Hello ,JSPang"console.log(inputEl) //输出获取到的DOM节点}return (<>{/*保存input的ref到inputEl */}<input ref={inputEl} type="text"/><button onClick = {onButtonClick}>在input上展示文字</button></>)
}
export default Example

8. 自定义Hooks函数

实例,自第一个实时监测浏览器窗口大小的Hooks函数
自定义Hooks函数,记住一定要用use开头

import React,{ useState ,useEffect ,useCallback } from 'react';
const useWinSize = () =>{const [size,setSize] = useState({width:document.documentElement.clientWidth,height:document.documentElement.clientHeight})
//useCallback,目的是为了缓存方法(useMemo是为了缓存变量)const onResize = useCallback(() => {setSize({width: document.documentElement.clientWidth,height: document.documentElement.clientHeight})},[])useEffect(()=>{window.addEventListener('resize',onResize)return ()=>{window.removeEventListener('resize',onResize)}},[])return size
}//组件中使用
const MyHooks = ()=>{const size = useWinSize()
return <div>size:{size.width}x{size.height}</div>
}
export default MyHooks

关于React Hooks使用相关推荐

  1. react hooks使用_为什么要使用React Hooks?

    react hooks使用 The first thing you should do whenever you're about to learn something new is ask your ...

  2. react hooks使用_如何使用React和Hooks检测外部点击

    react hooks使用 by Andrei Cacio 通过安德烈·卡西奥(Andrei Cacio) 如何使用React和Hooks检测外部点击 (How to detect an outsid ...

  3. react hooks使用_如何使用Hooks将React类组件转换为功能组件

    react hooks使用 by Balaganesh Damodaran 通过Balaganesh Damodaran 如何使用Hooks将React类组件转换为功能组件 (How to conve ...

  4. 探React Hooks

    前言 众所周知,hooks在 React@16.8 中已经正式发布了.而下周周会,我们团队有个同学将会仔细介绍分享一下hooks.最近网上呢有不少hooks的文章,这不免激起了我自己的好奇心,想先行探 ...

  5. 使用React Hooks你可能会忽视的作用域问题

    前言 其实React Hooks已经推出来一段时间了,直到前一阵子才去尝试了下,看到的一些博客都是以API的使用居多,还有一些是对于原理的解析.而我这篇文章想写的是关于React Hooks使用中的作 ...

  6. dw按钮图片滚动js_使用 React Hooks 实现仿石墨的图片预览插件(巨详细)

    点击上方"前端教程",选择"星标" 每天前端开发干货第一时间送达! 作者:DARRELL https://juejin.im/post/5e9bf299f265 ...

  7. 通过 React Hooks 声明式地使用 setInterval

    2019独角兽企业重金招聘Python工程师标准>>> 本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: se ...

  8. mounty不可重新挂载因为先前没有完全卸载_【译】React Hooks测试完全指南

    原文地址:https://www.toptal.com/react/testing-react-hooks-tutorial 2018年底,React在16.8版本中引入了Hooks.它们(译注:指R ...

  9. 【译】什么是React Hooks

    原文:What are React Hooks? 作者:Robin Wieruch 译者:博轩 React Hooks 于 2018年10月的React Conf 中引入,作为在 React 函数组件 ...

  10. 理解 React Hooks

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由志航发表于云+社区专栏 TL;DR 一句话总结 React Hooks 就是在 react 函数组件中,也可以使用类组件(classe ...

最新文章

  1. httpservletrequest_了解HttpServletRequest 对象 基本应用
  2. JavaScript函数的调用
  3. mysql双主同步一个库,CNESA
  4. sharepoint 2010 使用WinForm获取 SPSite对象
  5. bem什么意思_bem是什么意思_bem的翻译_音标_读音_用法_例句_爱词霸在线词典
  6. iphone如何信任软件_苹果企业开发者证书成漏洞 盗版商发布破解版iPhone应用
  7. SpringBoot - 多Profile使用与切换
  8. 输入mysql -v_Mysql数据库使用笔记
  9. HTML的基本知识(四)——文本格式化标签
  10. From Apprentice To Artisan 翻译 17
  11. springboot 对接海康设备
  12. easyui表格 序号如何进行自适应宽度
  13. 企业估值研究到底从何处着手?
  14. python英语词汇量测试_python英语单词测试小程序
  15. 淘宝关键词搜索采集商品价格销量接口分析商品价格走势(商品列表接口,商品销量接口,商品价格接口,分类ID采集精准商品数据接口)接口代码对接流程
  16. 每个架构师都应该了解的理论:康威定律
  17. Response.Flush()的作用
  18. 有道翻译软件下载地址
  19. python生成X~N(μ,σ^2)正态分布数据。(均值为μ,标准差为σ)
  20. android---加速传感器

热门文章

  1. Easy Audio CD Burner 算法分析及逆向推算(图)
  2. java学习电子书_Java学习指南(第4版)(上册) 中文完整pdf扫描版[179MB]
  3. JavaScript闭包理解
  4. 上位机与下位机的串口通信实践
  5. Win10应用商店无法下载XBOX怎么办?
  6. 360手机助手pc版 v2.4.0.1265 官方版
  7. 佳博打印机打印条码和二维码的方法
  8. PL(Planet)卫星群遥感数据介绍及应用
  9. 计算机基础第四章excel,计算机基础第4次作业 第四章 Excel知识题
  10. Arping协议以及使用方法