• 第9章:React Hooks


    第9章:React Hooks

    使用 hooks 理由

    1. 高阶组件为了复用, 导致代码层级复杂
    2. 生命周期的复杂
    3. 写成 functional 组件, 无状态组件, 因为需要状态, 又改成了 class, 成本高

    useState (保存组件状态)

    const [state, setstate] = useState(initialState)
    
    • 1

    useEffect (处理副作用)和 useLayoutEffect (同步执行副作用)

    Function Component 不存在生命周期, 所以不要把 Class Component 的生命周期概念搬过来试图对号入座。

    useEffect(() => {
        //effect
        return () => {
            //cleanup
        };
    }, []) // 依赖的状态;空数组, 表示不依赖
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    不要对 Dependencies 撒谎, 如果你明明使用了某个变量, 却没有申明在依赖中, 你等于向 React 撒了谎, 后果就是, 当依赖的变量改变时, useEffect 也不会再次执行, eslint 会报警告 Preview 页面改造成函数式组件, 在路径上从 id=1 切换到 id=2 也会自动重新加载, 比 class 组件方便。

    let id = props.match.params.myid
    useEffect(() => {
        axios.get(`/articles/${id}`).then(res => {
            settitle(res.data.title)
            setcontent(res.data.content)
            setcategory(res.data.category)
        })
    }, [id])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    useEffect 和 useLayoutEffect 有什么区别?

    简单来说就是调用时机不同, useLayoutEffect 和原来 componentDidMount & componentDidUpdate 一致, 在 react 完成 DOM 更新后马上同步调用的代码, 会阻塞页面渲染。而 useEffect 是会在整个页面渲染完才会调用的代码。官方建议优先使用 useEffect

    However, we recommend starting with useEffect first and only trying useLayoutEffect if that causes a problem.

    在实际使用时如果想避免页面抖动(在 useEffect 里修改DOM很有可能出现)的话, 可以把需要操作 DOM 的代码放在 useLayoutEffect 里。在这里做点 dom 操作, 这些 dom 修改会和 react 做出的更改一起被一次性渲染到屏幕上, 只有一次回流、重绘的代价。

    useCallback(记忆函数)

    防止因为组件重新渲染, 导致方法被重新创建, 起到缓存作用; 只有第二个参数 变化了, 才重新声明一次。

    var handleClick = useCallback(() => {
        console.log(name)
    }, [name])
     
    // 只有 name 改变后, 这个函数才会重新声明一次
    // 如果传入空数组, 那么就是第一次创建后就被缓存, 如果 name 后期改变了, 拿到的还是老的name
    // 如果不传第二个参数, 每次都会重新声明一次, 拿到的就是最新的 name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    useMemo 记忆组件

    useCallback 的功能完全可以由 useMemo 所取代, 如果你想通过使用 useMemo 返回一个记忆函数也是完全可以的。

    唯一的区别是:useCallback 不会执行第一个参数函数, 而是将它返回给你, 而 useMemo 会执行第一个函数并且将函数执行结果返回给你。所以在前面的例子中, 可以返回 handleClick 来达到存储函数的目的。

    所以 useCallback 常用记忆事件函数, 生成记忆后的事件函数并传递给子组件使用。而 useMemo 更适合经过函数计算得到一个确定的值, 比如记忆组件。

    useRef(保存引用值)

    const myswiper = useRef(null)
    
    
    • 1
    • 2

    useReducer和useContext(减少组件层级)

    import React from 'react'
    
    var GlobalContext = React.createContext()
    
    // 注意此时的 reduecer 返回值是一个对象 {isShow:false,list:[]}
    function App(props) {
        let [state, dispatch] = useReducer(reducer, {isShow: true, list: []})
        return {dispatch}}>
            
    {state.isShow ?
    我是选项卡
    : null}{props.children}
    } function Detail() { var {dispatch} = useContext(GlobalContext) useEffect(() => { //隐藏 dispatch({type: "Hide", payload: false}) return () => { //显示 dispatch({type: "Show", payload: true}) }; }, []) return
    detail
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    自定义hooks

    当我们想在两个函数之间共享逻辑时, 我们会把它提取到第三个函数中。

    必须以 use 开头吗?

    必须如此。这个约定非常重要。不遵循的话, 由于无法判断某个函数是否包含对其内部 Hook 的调用, React 将无法自动检查你的 Hook 是否违反了 Hook 的规则。

  • 相关阅读:
    【树莓派 Pico 基于MicroPython编程Thonny开发】
    Selenium自动化测试之Selenium IDE
    Centos - 磁盘快照
    【Python】QTreeWidget树形结构添加
    Spring核心与设计思想
    如何部署自带离线iClient包的Docker版iServer
    前端性能优化:利用防抖节流实现图片懒加载
    Redis缓存击穿及解决问题
    GCC多平台编译会遇到小问题
    ESP8266-Arduino编程实例-TMP175数字温度传感器驱动
  • 原文地址:https://blog.csdn.net/m0_51180924/article/details/126389087