zoukankan      html  css  js  c++  java
  • react hooks 理念之代数效应

    hooks 是为了践行 代数效应,目的是把副作用从函数调用中剥离出去。

    代数效应的自我理解:在代数中函数表达式为 y = f(x),代数中的函数相同的入参必然会得到相同的结果,是没有副作用的。在程序中对应的就是纯函数。而 react 的 hooks 就是为了让组件看起来更像是一个纯函数,需要将函数的副作用从组件中剥离出去。

    比如,我们有一个通过两篇文章 id 获取评论总数的函数 getTotalCommentNum,里面调用 getCommentNum 方法获取每篇文章的评论数,如下代码所示。

    function getTotalCommentNum(id1, id2) {
        const num1 = getCommentNum(id1);
        const num2 = getCommentNum(id2);
        return num1 + num2;
    }
    

    现在有个问题,获取评论数理应是需要调用接口的,是个异步方法,那么上面的代码要想正确执行则需要改成 async await 函数才行,但是改成 async await 函数后,在一个其它函数 fn 中调用 getTotalCommentNum 函数,那么这个函数 fn 也要写成 async 才行,async await 是有传导性的。那有没有办法解决呢?目前是没有这样的语法的。。。
    下面我们就先虚构一个新的语法来解决这个问题:

    function getCommentNum(id) {
        const num = perform id;
        return num;
    }
    
    try {
        getTotalCommentNum(1, 2);
    } handle(id) {
        // 这里即可以执行异步操作,也可以执行同步操作,最终调用 resume 返回值并交回调用栈即可
        fetch(`xxxx/${id}`).then(res => res.json()).then((num) => {
            resume num;
        })
    }
    

    我们在编写 getCommentNum 的时候,使用了 perform 关键字,而在调用 getTotalCommentNum 的时候使用了 try handle 语法。在 try 中调用 getTotalCommentNum,然后执行到 const num1 = getCommentNum(id1),代码进入 getCommentNum 中,遇到了 perform 关键字,此时就会跳转到 handle 中,并将 perform 后的值(这里即为 id)传入 handle,在 handle 中我们拿到这个 id,就可以进行异步操作,异步操作结束后使用 resume (类似 resolve)关键字返回值,流程就回到了 const num1 = getCommentNum(id1) 这里,num1 获取到了返回的值,继续往下执行。
    如果有这样的语法我们就可以编写出 getTotalCommentNum 这样的没有 async await 的传导性,同步异步相同写法,不会有异步请求副作用的函数。

    这和 react 有什么关系呢?
    代码改动:

    // getTotalCommentNum 变成了 TotalCommentNum 就是一个函数式组件
    function TotalCommentNum({id1, id2}) {
        const num1 = useCommentNum(id1);  // 这里改成了 useCommentNum hooks
        const num2 = useCommentNum(id2);
        return num1 + num2;
    }
    // 自定义 hooks
    function useCommentNum(id) {
        const [num, setNum] = useState(0);
        useEffect(() => {
            fetch(`xxxx/${id}`).then(res => res.json()).then((num) => {
                setNum(num);
            })
        }, [id]);
        return num;
    }
    

    这里 TotalCommentNum 函数组件中将异步请求剥离到了 useCommentNum 中,而 useCommentNum 无论是异步还是同步的,并不会影响 TotalCommentNum 函数组件的写法。
    所以说 hooks 是为了践行代数效应。

  • 相关阅读:
    渐统江湖的项目原型生成工具 Maven Archetype
    ANT的安装/配置笔记
    Maven服务器安装
    为什么Eclipse替代不了Maven
    Maven入门实战笔记11节[711]
    Maven入门实战笔记11节[15]
    Maven多模块项目中应用maventomcatplugin热部署
    使用 CXF、Spring、Maven 创建一个 SOAP 客户端
    maven2创建的archetypeArtifactId类型大全
    JdbcDaoSupport应用
  • 原文地址:https://www.cnblogs.com/3body/p/15415467.html
Copyright © 2011-2022 走看看