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. css 百分比继承关系的探讨

    引入:近日在回顾css基础的时候发现了一个有趣的问题,就是css在继承百分比类属性的时候是继承百分比后再根据父级宽高计算,还是继承父级根据百分比计算过后的绝对值.下面举一个简单的例子来描述这一个问题, ...

  2. visualStudio 无法登陆

    如果遇到 visualStudio 无法登陆,可以看下我的方法,可能有用 尝试关闭代理 打开设置.网络.代理,关了它,试试 如果遇到下面的问题: 我们无法刷新此账户的凭据 No home tenant ...

  3. js基础——function类型

    1.函数声明方式 1)普通声明方式  function box(num1,num2){       return num1 + num2;  } 2)使用变量初始化函数 var box = funct ...

  4. P1014 高精度减法

    题目描述 给你两个很大的正整数A和B,你需要计算他们的差. 输入格式 输入一行包含两个正整数A和B,以一个空格分隔(A和B的位数都不超过 \(10^5\) ,但是B有可能比A大) 输出格式 输出一行包 ...

  5. 关于POSTMAN做并发压测

    一开始我个人在做测试时用到了POSTMAN,用了两种方式做测试, 第一种: 测试发现这种方式是阻塞排队,我让接口睡两秒,这100次请求间隔就是2秒,是串行执行 于是想到第二种,在一个collectio ...

  6. H3C 端口绑定基本配置

  7. 初识Ubuntu 18.04(更换系统头像,截图,sy)

    其实我认识ubuntu也有一段时间了,只是我一直沉迷Windows无法自拔,但是熟悉一下ubuntu的环境对于各项比赛以及今后的工作还是很有用处的,不过在未来的很长一段时间里,我只会以一个普通用户的身 ...

  8. AS优化

    第一步:打开AS安装所在的位置,用记事本打开“红色框”选中的文件. 如图: 第二步:打开“studio64.exe.vmoptions”文件后修改里面的值,修改后如下: 1 2 3 4 5 6 7 8 ...

  9. HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap的区别

    Map是Java最常用的集合类之一.它有很多实现类,我总结了几种常用的Map实现类,如下图所示.本篇文章重点总结几个Map实现类的特点和区别: 特点总结: 实现类 HashMap LinkedHash ...

  10. CSP201903-2二十四点

    如图所示先处理乘号和除号,再处理加减. #include<bits/stdc++.h> using namespace std; ];int main(){ int n; cin>& ...