useState

用来声明状态变量。

import React, { useState } from 'react';
// ...
const [ count , setCount ] = useState(0);
// ...
  • count 声明的变量
  • setCount 设用来更新变量的函数
  • 0 初始值
  • 多个状态声明不能出现在条件判断语句中

useEffect

用来代替生命周期函数。

import React, { useEffect } from 'react';

useEffect(()=>{
// some code
})
  • 第一次组件渲染和每次组件更新都会执行这个函数
  • useEffect中的函数的执行不会阻碍浏览器更新视图,这些函数是异步的

使用 useEffect 实现类似 componentWillUnmount

useEffect(()=>{
return () => {
// some code
}
})
  • 返回一个函数实现解绑
  • 但是这样会导致每次状态发生变化,useEffect 都进行解绑
useEffect(()=>{
return () => {
// some code
}
}, [])

使用第二个参数,制定哪些状态发生变化时再解绑

useContext

跨越组件层级直接传递变量,实现状态共享。

  • useContext 解决的是组件之间值传递的问题
  • redux 解决的是应用中统一管理状态的问题
  • useContext 通过和 useReducer 的配合使用,可以实现类似 Redux 的作用

Outer 组件

import React, { createContext } from 'react'
const ValueContext = createContext()
function Outer(){
return (
<>
<ValueContext.Provider value={'我是传向 Inner 组件的值'}>
<Inner />
</ValueContext.Provider>
</>
)
}
export default Outer;
  • 使用 createContext 创建 context
  • 使用 createContext 同时生成组件
  • 闭合标签将组件包裹

Inner 组件

import React, { useContext  } from 'react'
const value = useContext(CountContext)
function Inner(){
return (
<>
<p>{value}</p>
</>
)
}
export default Inner;

使用 useContext 来使用上下文

useReducer

用来实现类似 redux 功能

import React, { useReducer } from 'react';

function Demo(){
const [ count, dispatch ] = useReducer((state,action)=>{
switch(action){
case 'add':
return state+1
case 'sub':
return state-1
default:
return state
}
},0)
return (
<>
<h2>分数:{count}</h2>
<button onClick={()=>dispatch('add')}>加</button>
<button onClick={()=>dispatch('sub')}>减</button>
</>
)
} export default Demo
  • state 第一个参数 状态
  • action 控制业务逻辑的判断参数

模拟 Redux

  • useContext:可访问全局状态,避免一层层的传递状态
  • useReducer:通过action的传递,更新复杂逻辑的状态

颜色共享组件 color.js

import React, { createContext,useReducer } from 'react';

export const ColorContext = createContext({})
export const UPDATE_COLOR = 'UPDATE_COLOR' const reducer = (state, action) => {
switch(action.type){
case UPDATE_COLOR:
return action.color
default:
return state
}
} export const Color = props => {
const [color, dispatch] = useReducer(reducer, 'blue')
return (
<ColorContext.Provider value = {{color,dispatch}}>
{props.children}
</ColorContext.Provider>
)
}
  • 用 {props.children} 来显示子组件
  • 将 color 和 dispatch 共享出去

showArea.js

import React , { useContext } from 'react';
import { ColorContext } from './color'; function ShowArea(){
const { color } = useContext(ColorContext)
return (<div style={{ color:color }}>字体颜色为{ color }</div>)
} export default ShowArea
  • 注意 引入 ColorContext 使用了大括号

Buttons.js

import React , { useContext } from 'react';
import { ColorContext, UPDATE_COLOR } from './color' function Buttons(){
const { dispatch } = useContext(ColorContext)
return (
<div>
<button onClick={()=>{dispatch({type:UPDATE_COLOR,color:"red"})}}>红色</button>
<button onClick={()=>{dispatch({type:UPDATE_COLOR,color:"yellow"})}}>黄色</button>
</div>
)
} export default Buttons

Demo.js

import React, { useReducer } from 'react';
import ShowArea from './ShowArea';
import Buttons from './Buttons';
import { Color } from './color'; //引入Color组件 function Demo(){
return (
<>
<Color>
<ShowArea />
<Buttons />
</Color>
</>
)
} export default Demo

useMemo

用来解决使用 React hooks 产生的无用渲染的性能问题。

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

function Demo(){
const [xiaohong , setXiaohong] = useState('小红待客状态')
const [zhiling , setZhiling] = useState('志玲待客状态')
return (
<>
<button onClick={()=>{setXiaohong(new Date().getTime())}}>小红</button>
<button onClick={()=>{setZhiling(new Date().getTime()+',志玲向我们走来了')}}>志玲</button>
<ChildComponent name={xiaohong}>{zhiling}</ChildComponent>
</>
)
} function ChildComponent({name,children}){
function changeXiaohong(name){
console.log('她来了,她来了。小红向我们走来了')
return name+',小红向我们走来了'
} const actionXiaohong = changeXiaohong(name)
return (
<>
<div>{actionXiaohong}</div>
<div>{children}</div>
</>
)
} export default Demo

点击志玲按钮,小红对应的方法执行,虽然结果没变,但是每次都执行,损耗性能。

function ChildComponent({name,children}){
function changeXiaohong(name){
console.log('她来了,她来了。小红向我们走来了')
return name+',小红向我们走来了'
} const actionXiaohong = useMemo(()=>changeXiaohong(name),[name])
return (
<>
<div>{actionXiaohong}</div>
<div>{children}</div>
</>
)
}

第二个参数 [name] 匹配成功,才会执行。

useRef

  • 用来获取React JSX中的DOM元素
  • 用来保存变量
import React, { useRef} from 'react';
function Demo(){
const inputEl = useRef(null)
inputEl.current.value = "给 input value属性 赋值"
return (
<>
<input ref={inputEl} type="text"/>
</>
)
} export default Demo
import React, { useRef, useState, useEffect } from 'react'

function Demo(){
const inputEl = useRef(null)
inputEl.current.value="给 input value属性 赋值" const [text, setText] = useState('默认值')
const textRef = useRef() useEffect(()=>{
textRef.current = text
}) return (
<>
<input ref={inputEl} type="text"/>
<input value={text} onChange={(e)=>{setText(e.target.value)}} />
</>
)
} export default Demo
  • text 每次发生变化,将值保存到 useRef 中
  • 使用 useEffect 实现每次状态变化都进行变量重新赋值
  • 很少用到这个功能(保存变量)

自定义 Hooks

编写自定义函数实现获取浏览器窗口

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

function useWinSize(){
const [ size , setSize] = useState({
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
}) const onResize = useCallback(()=>{
setSize({
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
})
},[]) useEffect(()=>{
window.addEventListener('resize',onResize)
return ()=>{
window.removeEventListener('resize',onResize)
}
},[]) return size;
} function Demo(){
const size = useWinSize()
return (
<div>页面Size:{size.width} x {size.height}</div>
)
} export default Demo
  • 命名要使用 use 开头以确认该函数是自定义 Hook 而不是组件
  • useCallback 用来缓存方法 ( useMemo 是为了缓存变量)
  • 第一次进入方法时用 useEffect 来注册 resize 监听事件
  • 防止一直监听所以在方法移除时,使用return的方式移除监听
  • 最后在 Demo 组件中使用

文章参考

  • 官方文档
  • 哔哩哔哩up主技术胖的 视频

React Hooks 一步到位的更多相关文章

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

    本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: setInterval 用起来没你想的简单. Ryan Florence 在他 ...

  2. 初探React Hooks & SSR改造

    Hooks React v16.8 发布了 Hooks,其主要是解决跨组件.组件复用的状态管理问题. 在 class 中组件的状态封装在对象中,然后通过单向数据流来组织组件间的状态交互.这种模式下,跨 ...

  3. React hooks实践

    前言 最近要对旧的项目进行重构,统一使用全新的react技术栈.同时,我们也决定尝试使用React hooks来进行开发,但是,由于React hooks崇尚的是使用(也只能使用)function c ...

  4. 理解 React Hooks

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

  5. React Hooks新特性学习随笔

    React Hooks 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性. 前言 本篇主要以讲几个常用的api为主. 1.u ...

  6. 关于React Hooks,你不得不知的事

    React Hooks是React 16.8发布以来最吸引人的特性之一.在开始介绍React Hooks之前,让咱们先来理解一下什么是hooks.wikipedia是这样给hook下定义的: In c ...

  7. react hooks 全面转换攻略(三) 全局存储解决方案

    针对 react hooks 的新版本解决方案 一.redux维持原方案 若想要无缝使用原来的 redux,和其配套的中间件 promise,thunk,saga 等等的话 可以使用 redux-re ...

  8. react新特性 react hooks

    本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...

  9. 30分钟精通React今年最劲爆的新特性——React Hooks

    你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗? --拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function. 你还在为搞不清使用哪个生命周 ...

随机推荐

  1. Notice: Use of undefined constant - assumed ' '

    昨天看手册的时候有两个范例,懒得写了,直接复制,测试一下,结果报Notice; 反复检查无果,最后, 手动敲了一遍,居然正常了,汗.... 总结:偷懒害人

  2. Docker Desktop: Error response from daemon: driver failed programming external connectivity on endpoint xxx 问题

    右击任务栏 Docker 图标 `Restart` 或 `Quit Docker Deskto` 后之前正常的 zookeeper 容器不会自动启动 通过命令 docker start zk1 启动报 ...

  3. requests库结合selenium库共同完成web自动化和爬虫工作

    我们日常工作中,单纯的HTTP请求,程序员都倾向于使用万能的python Requests库.但大多数场景下,我们的需求页面不是纯静态网页,网页加载过程中伴随有大量的JS文件参与页面的整个渲染过程,且 ...

  4. Linux中安装软件和各种常用命令

    1.Centos7中安装mysql5.7的链接:http://blog.csdn.net/fanpeizhong/article/details/73557202 2.修改mysql默认密码的链接:h ...

  5. ELK学习实验005:beats的一些工具介绍

    一 背景需求 Nginx是一个非常优秀的web服务器,往往Nginx服务会作为项目的访问入口,那么,nginx的性能保障就会变得非常重要,如果nginx的运行出现了问题就会对项目有较大的影响,所以,我 ...

  6. 一文带你了解 OAuth2 协议与 Spring Security OAuth2 集成!

    OAuth 2.0 允许第三方应用程序访问受限的HTTP资源的授权协议,像平常大家使用Github.Google账号来登陆其他系统时使用的就是 OAuth 2.0 授权框架,下图就是使用Github账 ...

  7. GNE: 4行代码实现新闻类网站通用爬虫

    GNE(GeneralNewsExtractor)是一个通用新闻网站正文抽取模块,输入一篇新闻网页的 HTML, 输出正文内容.标题.作者.发布时间.正文中的图片地址和正文所在的标签源代码.GNE在提 ...

  8. react 报红错误汇总

    react  报红错误汇总 一.Uncaught TypeError: Cannot read property 'value' of undefined 未知类型错:无法读取未定义的属性“value ...

  9. 「分块系列」「洛谷P4168 [Violet]」蒲公英 解题报告

    蒲公英 Description 我们把所有的蒲公英看成一个长度为\(n\)的序列(\(a_1,a_2,...a_n\)),其中\(a_i\)为一个正整数,表示第i棵蒲公英的种类的编号. 每次询问一个区 ...

  10. 个性化重排--Personalized Re-ranking for Recommendation

    推荐中的个性化重排--Personalized Re-ranking for Recommendation 这篇文章是阿里在ResSys'19发表的,主要贡献是在重排序阶段,引入了用户的相关信息,很符 ...