最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React Hooks上篇-简介

    正文概述 掘金(头号前端)   2021-03-19   416

    Hooks 要解决的问题

    组件之间的逻辑复用

    现有的常用方案是 render props 和 higher-order components ,同时也带了问题: 重新调整组件结构

    逻辑调用链长,难以理解

    形成组件的嵌套地狱

    复杂组件难以理解

    组件越来越复杂:

    初期简单的类组件随着功能的增多变得越来越复杂,也越来越难以拆分

    生命周期机制把相关的代码分离在不同的部分,把不相关的代码又合在一起,容易引入bug

    引入各种各样的库,提升项目复杂度

    类组件的冗杂

    类组件有许多不方便之处: this

    绑定事件处理程序

    代码冗长

    ......

    Hooks 核心思想

    减少组件嵌套,聚合相关逻辑,抽取细粒度的可复用组件

    Hooks 核心 API

    useState(initialState)

    import React, { useState } from 'react'
    
    function Count() {
      const [count, setCount] = useState(0)
      const [lazyState, setLazyState] = useState(() => expensiveComputation())
    
      return (
        <div>
          <p>lazy state {lazyState}</p>
          <p>you clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>+</button>
          <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
        </div>
      )
    }
    

    useEffect(fn, [dependencyList])

    import React, { useState, useEffect } from 'react'
    
    function List() {
      const [dataList, setDataList] = useState([])
      const [searchValue, setSearchValue] = useState('123')
      
      useEffect(() => {
        consoloe.log(searchValue)
      })
      
      useEffect(() => {
        async function fetchData(value) {
          const result = await fetch('xxx')
          setDataList(result.data);
        }
        fetchData(searchValue)
      }, [searchValue])
    
      useEffect(() => {
        function scroll() {
            /* ... */
        }
        window.addEventListener('scroll', scroll)
        return () => {
          window.removeEventListener('scroll', scroll)
        }
      }, [])
    
      return (
        <div>
          <input
            value={searchValue}
            onChange={e => setSearchValue(e.target.value)}
          />
          <ul>
            <li>
              {dataList.map((data, index) => <li key={index}>{data.text}</li>)}
            </li>
          </ul>
        </div>
      )
    }
    

    useLayoutEffect(fn, [dependencyList])

    同步版的 useEffect,常用于 dom 更新时的元素位置、样式等属性的计算

    Hooks 附加 API

    useReducer(reducer, initialState)

    import React, { useState, useReducer } from 'react'
    
    /* base implements */
    function useReducer(reducer, initialState) {
      const [state, setState] = useState(initialState)
      function dispatch(action) {
        const newState = reducer(state, action)
        setState(newState)
      }
      return [state, dispatch]
    }
    
    function reducer(state = 0, action) {
      switch(action.type) {
        case 'increase': return state - 1
        case 'decrease': return state + 1
        default: return state
      }
    }
    
    
    function Count() {
      const [count, dispatch] = useReducer(reducer, 0)
      return (
        <div>
          <p>you clicked {count} times</p>
          <button onClick={() => dispatch({action: 'increase'})}>+</button>
          <button onClick={() => dispatch({action: 'decrease})}>-</button>
        </div>
      )
    }
    

    useCallback(fn, [dependencyList])

    import React, { useState, useCallback, memo } from 'react'
    
    const Button = memo(props => {
      useEffect(() => {
        console.log('rendered')
      })
    
      return (
        <button onClick={props.onClick}>{props.children}</button>
      )
    })
    
    function Counter({initialCount = 0}) {
      const [count, setCount] = useState(initialCount);
      
      const memoClick = useCallback(() => {
        setCount(prevCount => prevCount + 1)
      }, [])
    
      return (
        <>
          Count: {count}
          <Button onClick={memoClick}>+</Button>
          <Button onClick={() => setCount(count - 1)}>-</Button>
        </>
      );
    }
    

    useMemo(() => fn, [dependencyList])

    import React, { useState, useCallback, useMemo } from 'react'
    
    function Counter({initialCount = 0}) {
      const [count, setCount] = useState(initialCount);
      
      // useCallback(fn, deps) is equivalent to useMemo(() => fn, deps)
      const memoClick = useMemo(() => () => {
        setCount(prevCount => prevCount + 1)
      }, [])
      /*...*/
    }
    
    

    useRef(initialValue)

    import React, { useRef } from 'react'
    
    function TextInputWithFocusButton() {
      const inputEl = useRef(null)
      const onButtonClick = () => {
        inputEl.current.focus()
      }
      return (
        <>
          <input ref={inputEl} type="text" />
          <button onClcik={onButtonClick}>Focus the input</button>
        </>
      )
    }
    
    function Button() {
      const count = useRef(null)
      return (
        <button>rendered {count.current++} times</button>
      )  
    }
    

    Hooks 推荐规则

    Only Call Hooks at the Top Level

    Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function.

    Only Call Hooks from React Functions

    Call Hooks from React function components. Call Hooks from custom Hooks

    延伸阅读

    Hooks API Reference

    Hooks FAQ

    useEffect 完整指南

    如何错误使用useCallback


    起源地下载网 » React Hooks上篇-简介

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元