Preact 是 React 的缩略版, 体积非常小, 但五脏俱全. 如果你想了解 React 的基本原理, 可以去学习学习 Preact 的源码, 这也正是本文的目的。 Preact 的自定义组件是基于 Component 类实现的. preact 也实现了 hooks 机制,实现代码也就百来行,让我们来体会体会. hooks 功能本身是没有集成在 Preact 代码库内部的,而是通过preact/hooks导入 import { h } from 'preact'; import { useEffect } from 'preact/hooks'; function Foo() { useEffect(() => { 实际上 Preact 提供了options对象来对 Preact diff 进行扩展,options 类似于 Preact 生命周期钩子,在 diff 过程中被调用(为了行文简洁,上面的代码我忽略掉了)
在 Preact 中,当 signal 的值发生变化时,从组件内访问 signal 的属性会自动重新渲染组件。 安装 可以通过将 @preact/signals 包添加到项目中来安装 Signals: npm install @preact/signals 4. == todo); } 4.2 构建用户界面 现在我们创建了所有的状态,接下来需要编写用户界面,这里使用了 Preact。 import { createContext } from "preact"; import { useContext } from "preact/hooks"; // 创建 App 状态 function 总结 Signals 是 Preact 最近新出的特性,目前还不稳定,不建议在生产环境使用,如果想尝试,可以考虑在小型项目中使用。
在 Preact 中,当 signal 的值发生变化时,从组件内访问 signal 的属性会自动重新渲染组件。 安装可以通过将 @preact/signals 包添加到项目中来安装 Signals:npm install @preact/signals4. == todo);}4.2 构建用户界面现在我们创建了所有的状态,接下来需要编写用户界面,这里使用了 Preact。 import { createContext } from "preact";import { useContext } from "preact/hooks";// 创建 App 状态function 总结Signals 是 Preact 最近新出的特性,目前还不稳定,不建议在生产环境使用,如果想尝试,可以考虑在小型项目中使用。
紧接上节,Preact组件从vnode到真实html的过程发生了什么? Component{} 定义的 //首先是对自己的组件实例化 inst = new Ctor(props, context); //然后再在我们实例化的组件,去获得一些Preact 所以, 这就能说明了Preact(React也一样)父子组件的生命周期执行顺序了 parentWillMount -> parentRender -> childWillMount -> childRender
目前看来,Preact是最好的备胎。 Preact肯定是读过《一个备胎的自我休养》,充分考虑到了开发者迁移的痛苦,所以,最理想情况,迁移到Preact只要修改四行,就搞定了。 先是在package.json中增加preact和preact-compat,其中preact-compat用来保证preact和React之间的接口兼容。 的引用全都转移为使用preact-compat。 preact,希望那时候我们别手忙脚乱就好。 基于这个原则,我们不会在现有代码中去用特定于preact的功能,我们只要关心那些功能React有但是preact没有,这是需要避免的危险区。
本文通过对preact的hook源码分析,理解和掌握react/preact的hook用法以及一些常见的问题。 对于 preact的hook分析,我们很容易旧记住 hook 的使用和防止踩一些误区 preact hook 作为一个单独的包preact/hook引入的,它的总代码包含注释区区 300 行。 2、为什么 hook 不能放在 条件语句里面 3、为什么不能在普通函数执行 hook 基础 前面提到,hook在preact中是通过preact/hook内一个模块单独引入的。 preact hook 的实现对于原有的 preact 是几乎零入侵。它通过暴露在preact.options中的几个钩子函数在preact的相应初始/更新时候执行相应的hook逻辑。 总结: preact和react在源码实现上有一定差异,但是通过对 preact hook 源码的学习,对于理解 hook 的很多观念和思想是非常有帮助的。
自最初发行以来,Preact的维护者已经发布了多个版本,以解决问题并添加功能。在2019年10月,Preact X 发布了一些更新,旨在解决常见的痛点并改善现有功能。 Preact X 的新功能和改进 Preact的维护者进行了重大改进,以支持许多最新的React功能。让我们回顾一些最有趣的新功能。 Preact X提供了许多开箱即用的Hooks以及创建自定义Hooks的功能。你可以从 preact/hooks 或 preact/compat 导入Hooks。 // Preact 8.x import React from "preact-compat"; // Preact X import React from "preact/compat"; 现在, Preact X还直接支持CSS自定义属性以对Preact组件进行样式设置。
Preact替换React Preact是一个跟React同样使用ES2015 API,精简到3KB的替代方案。 最近发布的PWA,例如Lyft, Uber和 Housing.com都在生产环境使用了Preact。 注意:如果你的项目是React开发的,并且你想换成Preact? 理想情况下,您应该使用preact和preact-compat来进行开发,生产和测试。 这可以让你在早期发现任何交互操作性错误。 如果你只想在Webpack中仅使用别名preact和preact-compat生成构建(例如,如果你最开始使用Enzyme),请确保在部署到服务器之前彻底测试一切正常工作。 你可以在你的Webpack里面配置alias,react对应preact-compat,react-dom也对应preact-compat。
; enqueueRender(this); }, setState的定义如上,代码逻辑很容易看出 1、prevState若不存在,将要更新的state合并到prevState上 2、可以看出Preact 通过理清Preact的setState的执行原理。 应该是用于处理一个组件在一次流程中调用了两次setState的情况。 // 例如这里的handleClick是绑定click事件 handleClick = () =>{ // 注意,preact中setState后state的值是会马上更新的 this.setState 在Preact中是加2的!!!!通过分析Preact的setState可以解释这个原因。 在上面的语句3,extend函数调用后,当前的state值已经改变了。
为何使用Preact MVVM框架的流行,在一定程度上已经影响了前端开发者的思考模式,我们不再以命令式的方式操作DOM,而是交由框架完成,极大提高了开发效率。 相比于使用React,Preact更符合我们的要。Preact是React的轻量级替代方案,体积仅有3kB,并且拥有与React相同的API(官网如是说)。 开发过程 Preact提供了脚手架工具,并且也能与其他构建工具如Webpack、Rollup等整合。可以参考:preactjs.com/guide/v10/g… 。 部分分离,借助JSX,可以做到all in JS,这也是我们选择Preact的重要原因之一。 使用Preact示例如下: import { h, render } from 'preact' const shadowHost = document.createElement("div"); document.body.appendChild
用过Preact的人都知道,在每个JS文件之前,都需要写 /** @jsx h */,那这句话是什么作用呢? 先从JSX说起。 args) : null; return new Vnode( nodeName, attributes, children ); } 接着在render()函数里将其渲染成一个真实的DOM Preact (children || []).forEach(function(child){ //使用递归渲染 node.appendChild(Preact.render }) } container.appendChild(node) } } 接着,调用render这个方法就可以渲染出想要的结果 Preact.render 总结一下: 其实Preact的渲染的还是很简单的,整个过程就是 1、Babel解析JSX 2、h函数将解析后JSX节点转成虚拟DOM 3、render函数把它转成真实的节点 当然这个例子还很简单,对于render
用过Preact的人都知道,在每个JS文件之前,都需要写 /** @jsx h */,那这句话是什么作用呢? 先从JSX说起。 args) : null; return new Vnode( nodeName, attributes, children ); } 接着在render()函数里将其渲染成一个真实的DOM Preact (children || []).forEach(function(child){ //使用递归渲染 node.appendChild(Preact.render }) } container.appendChild(node) } } 接着,调用render这个方法就可以渲染出想要的结果 Preact.render 总结一下: 其实Preact的渲染的还是很简单的,整个过程就是 1、Babel解析JSX 2、h函数将解析后JSX节点转成虚拟DOM 3、render函数把它转成真实的节点 当然这个例子还很简单,对于render
React与Preact的异同。 而Preact也有提供preact-redux和preact-router,甚至还有帮助Preact做同构直出的preact-render-to-string。 引入preact的时候,大概是这样的: import preact, { h, render, Component } from 'preact'; 而引入react的时候,大概是这样的: import 因此如果混合使用 react 和 preact,可以在使用 preact 的 jsx 文件里添加 /** @jsx h /(或者 /* @jsx preact.h */,如果你只 import preact 此处定义的是preact.h ["transform-react-jsx", { "pragma":"preact.h" }] 所以,你会看到编译后,有类似的代码: _preact2.default.h
Ryan Florence 发文介绍了 Remix 的最新动态:React Router v7 正式发布,支持 React Server Components (RSC),而 Remix v3 将基于 Preact Web 开发的热门全栈框架,近期通过一篇博客文章宣布了重大更新:React Router v7 正式发布,支持 React Server Components (RSC),而 Remix v3 将基于 Preact 的重构 Remix v3 被定位为对 Web 框架的重新构想,计划基于 Preact 重构。 Preact 是一个轻量级的 React 替代品,API 类似但体积更小、性能更高。Remix v3 旨在减少依赖、提升性能,并提供模块化工具包和内置组件库(如复兴的 Reach UI)! 以下是一个 Remix v3 的概念性示例(假设基于 Preact): // routes/index.tsx import { defineLoader } from'remix'; exportconst
一个简单的Preact代码如下 // 一个简单的Preact demo import { h, render, Component } from 'preact'; class Clock extends ().toLocaleTimeString(); return { time }; } } render(<Clock />, document.body); 调用了preact
Preact 是 React 的缩略版, 体积非常小, 但五脏俱全. 如果你想了解 React 的基本原理, 可以去学习学习 Preact 的源码, 这也正是本文的目的。 Preact 的自定义组件是基于 Component 类实现的. preact 也实现了 hooks 机制,实现代码也就百来行,让我们来体会体会. hooks 功能本身是没有集成在 Preact 代码库内部的,而是通过preact/hooks导入 import { h } from'preact'; import { useEffect } from'preact/hooks'; functionFoo() { useEffect 实际上 Preact 提供了options对象来对 Preact diff 进行扩展,options 类似于 Preact 生命周期钩子,在 diff 过程中被调用(为了行文简洁,上面的代码我忽略掉了)
前言 preact作为备胎,但是具有体积小,diff算法优化过的特点,简单活动页用上它是不错的选择。 但是考虑到react令人兴奋的新特性,preact并没有按时更新去完全支持它,更严重的是一些babel插件、一些库配合preact会有问题。所以,还是不得不迁移了。 如何迁移? 从alias改起 首先,一般是这样子接入preact的,使得我们代码里面毫无感觉我们用的是preact。 在webpack的alias里面配置: alias: { react: 'preact-compat', 'react-dom': 'preact-compat' }, 复制代码 必须保证后面用到this.state之前,对state有初始化,否则是null 3. preact相关的router迁移回react生态 首先,import的preact-router得换成react-router
如Preact产出的preact-render-to-string还有我现在的团队在用的fast-react-render,都是这个思路。 然而我一直都不喜欢这些替代库,特别是在同构的场景下。 而同时Preact等并没有Stream方案。 再次,从优化的角度来看,框架都是在演化的。今天我们可以为了性能换上Preact,明天也许就要为了性能去换上Xreact。 Preact的render方法因为默认是append行为,所以增加了一个preact-replace来和React行为做对比。 而且得益于checksum的加持,如果checksum是一致的(react栏),React的渲染时间在DOM节点较少的时候与Preact一致,在节点很多的情况下比Preact、其他方案的成绩要好一大截。 然而React毕竟有40多K,比起Preact还是要大不少。在开发m.uber里,提到了多次2G网络,我觉得也是影响Uber工程师选择Preact的关键因素。
jsx要转化成virtualDOM,首先经过babel,再经过h函数的调用形成virtualDOM。具体如下
Preact的diff算法,是将setState后的vnode与前一次的dom进行比较的,边比较边更新。 out, dom); recollectNodeTree(dom, true);//recollectNodeTree } } 对于子节点的diff Preact