在 React 项目中全量使用 Hooks

此文章只是整理了在 React 项目开发中经常使用的一些 Hooks,具体每一个的坑,以及详细解刨后续继续更新,并会加上连接。javascript

React Hooks

Hooks 只能用于函数组件当中。html

useState

import React, { useState } from 'react';

const Component = () => {
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>click<button>
  )
}
复制代码

此方法会返回两个值:当期状态和更新状态的函数。效果同 this.statethis.setState,区别是 useState 传入的值并不必定要对象,而且在更新的时候不会吧当前的 state 与旧的 state 合并。java

useEffect

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

let timer = null;

const Component = () => {
  const [count, setCount] = useState(0);
  
  // 相似于 class 组件的 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    document.title = `You clicked ${count} times`;
    
    timer = setInterval(() => {
      // events ...
    }, 1000)
    
    return () => {
      // 相似 componentWillUnmount
      // unmount events ...
      clearInterval(timer); // 组件卸载 移除计时器
    };
  }, [count]);
  
  // ...
}
复制代码

若是 useEffect 第二个参数数组内的值发生了变化,那么 useEffect 第一个参数的回调将会被再执行一遍。react

useCallback

import React, { useCallback } from 'react';

const Component = () => {
  const setUserInfo = payload => {}; // request api

  const updateUserInfo = useCallback(payload => {
    setUserInfo(Object.assign({}, userInfo, payload));
  }, [userInfo]);
  
  return (
    <UserCard updateUserInfo={updateUserInfo}/> ) } 复制代码

useCallback 会在二个参数的依赖项发生改变后才从新更新,若是将此函数传递到子组件时,每次父组件渲染此函数更新,就会致使子组件也从新渲染,能够经过传递第二个参数以免一些非必要性的渲染。web

在一些特殊状况下传递此参数还能够解决一些由静态做用域致使的问题。redux

useMemo

import React, { useMemo } from 'react';

const Component = () => {
  const [count, setCount] = useState(0);
 
  const sum = useMemo(() => {
    // 求和逻辑
    return sum;
  }, [count]);
  
  return <div>{sum}</div>
}
复制代码

useMemo 的用法跟 useCallback 同样,区别就是一个返回的是缓存的方法,一个返回的是缓存的值。上述若是依赖值 count 不发生变化,计算 sum 的逻辑也就只会执行一次,从而性能。api

这是以后更新的:useCallback 与 useMemo 详解 欢迎阅读。数组

Redux Hooks

useSelector

import { shallowEqual, useSelector } from 'react-redux';

const Component = () => {
  const userInfo = useSelector(state => state.userInfo, shallowEqual);
  
  // ...
}
复制代码

useSelector 的第二个参数是一个比较函数,useSelector 中默认使用的是 === 来判断两次计算的结果是否相同,若是咱们返回的是一个对象,那么在 useSelector 中每次调用都会返回一个新对象,因此因此为了减小一些不必的 re-render,咱们可使用一些比较函数,如 react-redux 自带的 shallowEqual,或者是 Lodash 的 _.isEqual()、Immutable 的比较功能。缓存

useDispatch

import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';

const Compnent = () => {
  const dispatch = useDispatch();
  const clearUserInfo = useCallback(
    () => dispatch({ type: 'clearUserInfo' }),
    [dispatch]
  );
  
  return (
    <button onClick={clearUserInfo}>click</buttn>
  )
}
复制代码

使用 dispatch 来调度操做,加上 useCallback 来减小没必要要的渲染。react-router

React Router Hooks

useHistory

import { useHistory } from 'react-router';

const Compnent = () => {
  const history = useHistory();
  
  return (
    <button onClick={() => history.push('/home')}>go home</buttn>
  )
}
复制代码

useHistory

import React, { useEffect } from 'react';
import { useLocation } from 'react-router';

const Compnent = () => {
  const location = useLocation();
  
  useEffect(() => {
    // ...
  }, [location])
  
  return (
    <button onClick={() => history.push('/home')}>go home</buttn>
  )
}
复制代码

URL一发生变化,他将返回新的 location

useParams

import { useParams, useEffect } from 'react-router';

const Component = () => {
  const params = useParams();
  
  const getUserInfo = () => {}; // request api
  
  useEffect(() => {
    // parms 的 uid 发生变化就会从新请求用户信息
    getUserInfo(params.uid);
  }, [params.uid]);
  
  // ...
}
复制代码

useParams 返回 react-router 的参数键值对

useRouteMatch

import { useRouteMatch } from 'react-router';

const Component = () => {
  const match = useRouteMatch('/login');
  
  // ...
}
复制代码

useRouteMatch 传入一个参数 path,用来判断当前路由是否能匹配上传递的 path,适用于判断一些全局性组件在不一样路由下差别化的展现。

结语

使用 Hooks 能为开发提高很多效率,但并不表明就要抛弃 Class Component,依旧还有不少场景咱们还得用到它,好比须要封装一个公共的可继承的组件...

参考

相关文章
相关标签/搜索