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='/'>