博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React Hooks 一步到位
阅读量:4082 次
发布时间:2019-05-25

本文共 5934 字,大约阅读时间需要 19 分钟。

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 (        <>            
)}export default Outer;
  • 使用 createContext 创建 context
  • 使用 createContext 同时生成组件
  • 闭合标签将组件包裹

Inner 组件

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

{value}

)}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 (       <>           

分数:{count}

)}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 (        
{props.children}
)}
  • 用 {props.children} 来显示子组件
  • 将 color 和 dispatch 共享出去

showArea.js

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

Buttons.js

import React , { useContext } from 'react';import { ColorContext, UPDATE_COLOR } from './color'function Buttons(){    const { dispatch } = useContext(ColorContext)    return (        
)}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 (        <>            
)}export default Demo

useMemo

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

import React , {useState,useMemo} from 'react';function Demo(){    const [xiaohong , setXiaohong] = useState('小红待客状态')    const [zhiling , setZhiling] = useState('志玲待客状态')    return (        <>                                    
{zhiling}
)}function ChildComponent({name,children}){ function changeXiaohong(name){ console.log('她来了,她来了。小红向我们走来了') return name+',小红向我们走来了' } const actionXiaohong = changeXiaohong(name) return ( <>
{actionXiaohong}
{children}
)}export default Demo

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

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

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

useRef

  • 用来获取React JSX中的DOM元素
  • 用来保存变量
import React, { useRef} from 'react';function Demo(){    const inputEl = useRef(null)        inputEl.current.value = "给 input value属性 赋值"    return (        <>                        )}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 (        <>                        {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 (        
页面Size:{size.width} x {size.height}
)}export default Demo
  • 命名要使用 use 开头以确认该函数是自定义 Hook 而不是组件
  • useCallback 用来缓存方法 ( useMemo 是为了缓存变量)
  • 第一次进入方法时用 useEffect 来注册 resize 监听事件
  • 防止一直监听所以在方法移除时,使用return的方式移除监听
  • 最后在 Demo 组件中使用

转载地址:http://itqni.baihongyu.com/

你可能感兴趣的文章
react相关
查看>>
Flex弹性盒子
查看>>
伪类与伪元素的区别
查看>>
延迟加载(Lazyload)三种实现方式
查看>>
前端性能优化的七大手段
查看>>
前端优化带来的思考,浅谈前端工程化
查看>>
Egg.js 源码分析-项目启动
查看>>
Egg.js 基本使用
查看>>
rxjs 源码分析1-(fromEvent)
查看>>
浏览器输入URL到 请求全过程以及相应的性能优化
查看>>
Redux的核心原理
查看>>
使用react hooks实现自己的context-redux
查看>>
JavaScript 编程规范(一)
查看>>
javascript常见知识点
查看>>
JavaScript-笔试题之indexOf() forEach() map方法重写 #
查看>>
React stopPropagation失灵
查看>>
从渲染原理到性能优化(一)-- 首次渲染
查看>>
从渲染原理到性能优化(二)
查看>>
从渲染原理到性能优化(二)-- 更新渲染
查看>>
js趣味算法思想
查看>>