文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

函数组件和函数式编程有关系么?

2024-11-30 04:57

关注

大家好,我卡颂。

长期使用React的同学应该知道,React中存在两种组件:

既然提到「类」和「函数」,那么很自然的,我们会进一步思考:

毕竟,如果类组件和OOP有关,那么OOP中的思想(继承、封装、多态...)也能指导类组件的业务开发(函数组件与FP的关系同理)。换言之,我们可以直接用这些编程范式的最佳实践指导React项目开发。

那么,「函数组件」和「函数式编程」究竟是什么关系呢?本文会围绕这个话题展开讲解。

编程范式与DSL

首先,我们应该明确,「框架语法」本质是一种DSL(领域相关语言),他是为了「某个特定领域的开发」量身定制的。

比如,React作为一款针对「view开发」的DSL,虽然不同的view使用的框架不同,比如:

但这些框架都大体遵循同一套DSL(React语法),这套DSL并不属于某一种编程范式,而应该被视为「不同编程范式中,更符合view开发的语言特性的集合」。

所以,作为React DSL的一部分,函数组件可以体现OOP的思想,类组件也能体现FP的思想。只要这些思想有利于「view开发」,就可以纳入DSL的语法中。

比如,下面的函数组件Header,是由WelcomeMessage与LogoutButton组件组合而成,这是OOP中的「组合优于继承」思想:

function Header(props) {
  return (
    
); }

再比如,下面的类组件Cpn中,要改变状态count,并不是通过突变(类似this.state.count++),而是调用this.setState,传入不可变数据:

class Cpn extends React.Component {
  // ...
  onClick() {
    const count = this.state.count;
    this.setState({count: count + 1});
  }
  render() {
    // ...
  }
}

「使用不可变数据」属于FP中的思想。

所以,当我们要深入了解某个React特性时,应该以如下顺序递进的思考:

如果我们用上述思考过程研究「函数组件与函数式编程的关系」,会发现:

这就是两者的关系 —— 函数组件属于多种编程范式(主要是OOP与FP)在React中最终的落地产物,其中借鉴了一部分FP的思想。

我们不应该将函数组件单纯视为FP在React中的具象体现。

那么,函数组件究竟是如何演进而来的呢?

函数组件的演进

让我们按照上述三步演进顺序思考。首先,React的开发理念践行了如下公式(即:UI是数据快照经过函数映射而来):

UI = fn(snapshot)

要落地这个理念,有两个要素需要实现:

在这里,FP中「不可变数据」更适合作为「数据快照」的载体,所以React中状态是不可变的,因为状态的本质是快照。

而「函数映射」的载体则没有特殊要求。在React中,每次触发更新,所有组件都会重新render,render的过程就是「函数映射」的过程,输入是props与state,输出是JSX。

与React相对的,Vue中组件则更符合OOP的理念,考虑如下App组件:

const App = {
  setup(initialProps) {
    const count = reactive({count: 0})
    const add = () => { count.value++ }
    return {count, add}
  }
  template: "...省略"
}

组件的setup方法只会在初始化时执行一次,后续触发更新时操作的都是同一个闭包中的数据。这里面的闭包就是OOP思想中的实例。

既然React对「函数映射」的载体没有特殊要求,那么类组件、函数组件都是可以的。

那为什么函数组件最终替代了类组件成为React开发的主流呢?很多同学认为「函数组件的Hooks可以更好的复用逻辑」这一点,是函数组件优于类组件的主要原因。

但实际上,基于装饰器的类开发模式早已被验证是优秀的逻辑复用模式,类组件配合TS装饰器的模式是行得通的。

主要原因还是 —— 函数组件能够更好的落地UI = fn(snapshot)这一理念。

刚才说过,公式中的snapshot是「快照」的含义。在React中,快照主要包括三类数据:

对于同一个组件,根据公式UI = fn(snapshot),相同的快照输入应该获得相同输出(JSX)。

但状态更新也可能触发「副作用」,比如请求数据、操作DOM...

在类组件中,这些「副作用」逻辑被分散在各个生命周期钩子函数中,React无法掌控。

而在函数组件中:

function UserList({id}) {
  // 异步请求数据
  const data = use(fetchUser(id));
  
  // ...
}

使用时:

加载中...
}>

总而言之,使用函数组件时,所有副作用都处于一种「受到管控」的状态,可以尽可能保证每次更新时「相同的快照输入,获得相同的JSX输出」,所以函数组件在React中才会发扬光大。

同时,这也契合了FP中的纯函数思想。

总结

「函数组件」并不是「函数式编程」在React中的具体实现,而是React的设计理念UI = fn(snapshot)落地的最好载体。

在React中,还吸收了其他编程范式中的优秀思想。FP只是其中影响React最深的一种。毕竟,一切落地都是为了践行最初的设计理念。

来源:魔术师卡颂内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯