react-router && react hooks

一、为什么要使用hooks?

1、无需在class组件中管理this,组件更轻量
2、在一个函数中聚合

二、内置的hooks

React提供的Hooks,仅允许在函数式组件中使用。

useState

useState接收state的默认值,返回该state和一个仅用于修改该state的函数。

useEffect

useEffect包含了React的ComponentDidMounted,ComponentShouldUpdate等执行副作用函数的钩子,useEffect返回的函数会在渲染内容销毁时被触发。同事useEffect可以接收第二个参数,类似于vue的watch函数,当且仅当参数二发生变化时才会执行副作用函数。

useContext

useContext接收一个context为参数,返回当前context注入的值,前提是在父级组件已经使用<Context.Provider> 包裹子组件,此时的useContext效果相当于之前使用context时的静态声明和this.context,useContext一方面提供了context上的值,另一方面标明了当前组件对context的依赖情况,当context内的属性发生变化时,即触发该组件的重渲染。(当某个值被多个组件所依赖,context可以提升我们组件的渲染性能)

useCallback
function cacheEffectFn (EffectFn, deps = []) {
    // 第二个参数代表依赖数组,如果依赖数组为空,则代表第一个入参将在组件内被永久缓存
    return useCallBack(EffectFn, deps)
}

由于函数式组件在每次渲染时都会重新执行,在函数中正常声明的函数在渲染的时候每次都会被重新创建,当我们有节流函数保存了timer的时候,此时如果有其他state发生变化,重新触发函数组件的执行,那么之前的timer将不会影响这次重新创建的timer,因此,我们需要useCallback或者useRef来对我们的节流函数进行缓存。

useMemo

useMemo相比于useCallback的区别在于,useCallback是根据依赖(deps)缓存第一个入参(callback)的。useMemo是根据依赖(deps)缓存第一个入参(callback)的返回值的,例如

// 此时calcValue内的函数只会在首次渲染时或者依赖项count被改变时执行
// 节省了每次渲染时的内存消耗
const calcValue = React.useMemo(() => {
    return Array(10000).fill('').map(v => /* 一些大量的计算 */v)
}, [count])
useRef

useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数,返回的ref对象在组件的整个生命周期内保持不变。

const UseUseRef = () => {
    const inputElement = useRef(null)
    const focuHandle = () => {
        if (inputElement.current) {
            inputElement.current.focus()
        }
    }
    return (
        <div className="content">
            <input ref={ inputElement }  placeholder="useRef API"/>
            <button onClick={ focuHandle }></button>
        </div>
    )
}

相比于createRef(null),useRef(null)将缓存ref.current所指向的dom对象,我们还可以用来缓存像函数或者大的堆变量以节省内存消耗。

三、react-router

react-router-dom是在react-router的基础上进行的封装,下面列举一些常见的路由组件

<!-- 提供history路由,操作history api控制路由变化,同时根据包裹的路由情况渲染对应路由 -->
<BrowserRouter />
<!-- 最常用的路由组件 -->
<Route>
<!-- 用于装饰组件,装饰后组件内部可以在this.props内获取到当前的路由信息 -->
<withRouter>
<!-- Link\NavLink导航 -->
<Link to='/'>
<NavLink to='/'>