zoukankan      html  css  js  c++  java
  • react Hooks

    一 什么是Hooks

       Hook 是react16.8新增特性

       Hook本身就是一类特殊的函数,他们可以为你的函数型组件注入一些特殊的功能,在不用编写类的情况下实用state 和其他react 特性

    二 为什么要使用react Hooks

       1、状态逻辑难以复用

       2、组成复杂难以维护

       3、类的this 指向性问题

       hooks 允许我们使用简单的特殊函数实现class 各种功能

    三、举例Hooks

    useState

    在 React 组件中,我们经常要使用 state 来进行数据的实时响应,根据 state 的变化重新渲染组件更新视图。

    因为纯函数不能有状态,在 hooks 中,useState就是一个用于为函数组件引入状态(state)的状态钩子。

    const [state, setState] = useState(initialState);
    

    useState 的唯一参数是状态初始值(initial state),它返回了一个数组,这个数组的第[0]项是当前当前的状态值,第[1]项是可以改变状态值的方法函数

    延迟初始化

    initialState 参数是初始渲染期间使用的状态。 在随后的渲染中,它会被忽略了。 如果初始状态是高开销的计算结果,则可以改为提供函数,该函数仅在初始渲染时执行:

    function Counter({initialCount = 0}) {
      // 初始值为1
      const [count, setCount] = useState(() => initialCount + 1);
      return (
        <>
          Count: {count}
          <button onClick={() => setCount(0)}>Reset</button>
          <button onClick={() => setCount(count + 1)}>+</button>
          <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
        </>
      );
    }

    函数式更新对比普通更新

    如果需要使用前一时刻的 state(状态) 计算新 state(状态) ,则可以将 函数 传递给 setState 。该函数将接收先前 state 的值,并返回更新的 state 

    useReducer

    useReducer 可以接受三个参数,第一个参数接收一个形如(state, action) => newState 的 reducer纯函数,使用时可以通过dispatch(action)来修改相关逻辑。

    第二个参数是 state 的初始值,它返回当前 state 以及发送 action 的 dispatch 函数。

    你可以选择惰性地创建初始 state,为此,需要将 init 函数作为 useReducer 的第三个参数传入,这样初始 state 将被设置为 init(initialArg)。



    //官方示例
    function countReducer(state, action) {
      switch (action.type) {
        case 'add':
          return state + 1;
        case 'minus':
          return state - 1;
        default:
          return state;
      }
    }
    function initFunc(initialCount) { return initialCount + 1; }


    function Counter({initialCount = 0}) {
      const [count, dispatch] = useReducer(countReducer, initialCount, initFunc);
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => { dispatch({ type: 'add' }); }} >
            点击+1
          </button>
          <button onClick={() => { dispatch({ type: 'minus' }); }} >
            点击-1
          </button>
        </div>
      );
    }
    

      

    对比useState可知,看起来我们的代码好像变得复杂了,但实际应用到复杂的项目环境中,将状态管理和代码逻辑放到一起管理,使我们的代码具有更好的可读性、可维护性和可预测性。

    useEffect 用于引用副作用

    useEffect(create, deps);

    副作用:

    对环境的改变即为副作用,如修改 document.title
    
    但我们不一定非要把副作用放在 useEffect 里面
    
    实际上叫做 afterRender 更好,每次render后执行
    

    用途

    一、作为 componentDidMount 使用,[ ] 作第二个参数
    
    二、作为 componentDidUpdate 使用,可指定依赖
    
    三、作为 componentWillUnmount 使用,通过 return
    
    四、以上三种用途可同时存在
    

      

     特点:

    如果同时存在多个 useEffect, 会按照出现次序执行
    

    useLayoutEffect

    useEffect 在浏览器渲染完成后执行
    
    useLayoutEffect 在浏览器渲染前执行
    

      

    function App1() {
        const [n, setN] = useState(0)
        const time = useRef(null)
        const onClick = () => {
            setN(i => i + 1)
            time.current = performance.now()
        }
        useLayoutEffect(() => {
            if (time.current) {
                console.log(performance.now() - time.current) //大概是0.7ms
            }
        })
        useEffect(() => {
            if (time.current) {
                console.log(performance.now() - time.current) //大概是2.7ms
            }
        })
        return (
            <div className="App">
                <h1>n: {n}</h1>
                <button onClick={onClick}>Click</button>
            </div>
        );
    }
    

      

    useMemo==》useCallback

    useCallback(x => console.log(x), [m]) 等价于

    useMemo( () => x => console.log(x), [m])

    对比useMemo,useMemo缓存的是一个值,useCallback缓存的是一个函数,是对一个单独的props值进行缓存

    举例:

    • 子组件onChange调用了父组件的handleOnChange
    • 父组件handleOnChange内部会执行setText(e.target.value)引起父组件更新
    • 父组件更新会得到新的handleOnChange,传递给子组件,对于子组件来说接收到一个新的props
    • 子组件进行不必要更新
    • handleOnChange被缓存了下来,尽管父组件更新了,但是拿到的handleOnChange还是同一个
    • 对比useMemo,useMemo缓存的是一个值,useCallback缓存的是一个函数,是对一个单独的props值进行缓存
    • memo缓存的是组件本身,是站在全局的角度进行优化


    参考 :https://juejin.im/post/6877012518183632910#heading-3 

    https://www.jianshu.com/p/1252be39c702

  • 相关阅读:
    c#序列化和反序列化list
    centos7安装oracle 11gr2
    centos7系统备份与还原
    FAT32和NTFS最大支持的单个文件大小分别是多大?
    linux挂载远程windows服务器上的ISO,给内网的服务器安装软件
    tomcat8启动慢原因及解决办法
    CentOS统的7个运行级别的含义
    对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)
    空侃简介
    linux环境部署
  • 原文地址:https://www.cnblogs.com/xiaoeshuang/p/13741659.html
Copyright © 2011-2022 走看看