Thoughts, stories and ideas.

优化useEffect中的网络请求

优化useEffect中的网络请求

前一篇文章中我们提到 useEffect 需要在组建重新渲染的时候清除 SideEffect,对于网络请求或者其他IO操作我们同样需要清除 SideEffect 从而避免 Race Condition 的问题。 例如我们通常可能有下面的代码来获取用户的最新的个人信息后显示在页面上: const Profile = ({uid}) => { const [name, setName] = useState('') useEffect(() => { fetch(name_url/${uid}) .then(res => res.json()) .then(setName) }, [uid]) return (
{}
) } 上面的代码在一般情况下并不会出现问题,但当 Profile 组件多次重新渲染然后用户通过其他方式修改了用户名,这时我们的页面显示的就有可能是旧的 name 也有可能是修改后的 name。 让我们尝试引入一个状态值,来判断当前组件是否需要渲染这一份数据: const Profile = ({ui
2 min read

useEffect 的相互竞争

在 React 的项目中我们经常会使用 useEffect 这个hook 去处理组件中的 SideEffect,为确保的组件在每次渲染时都得到同样的数据,React 在开发模式下会对每个 useEffect 函数执行2 次。这种情况如果我们没有正确清除 useEffect 带来的 SideEffect 的话就会形成一种相互竞争 或者 Race Condition。比如下面的例子: const Com = ({timeout, text}) => { const ref = useRef() useEffect(() => { setTimeout(() => { ref.textContent = text; }, timeout) }, [timeout]) return (
) } 当父级组件传入不同的值 3000, 3000ms 和 2000,2000ms时,组件会先显示 2000ms 然后3000ms而不是我们设想的只显示2000ms。 解决上面问题的方式就是在 useEffect 被清除的时候我们
1 min read
useEffect 的 SideEffect

useEffect 的 SideEffect

SideEffect 在函数式编程的概念里是对 impure function 造成影响的一种描述,而相对的另外一种没有 SideEffect 的函数就叫pure function。比如下面的两个例子中: function add(a, b) { return a + b;} function addRondom(a) { return a + Math.floor(Math.random()*10)} add 是一个 pure function ,因为只要它的输入是相同的那么你可以就保证它永远可以得到相同的值。而 addRondom 就如同函数名一样,相同的输入并不能保证得到相同的输出,因为我们无法确保 Math.floor(Math.random()*10 每次都会返回同样的值。 下面的例子中就是在 React 的组件中比较常见的 SideEffect : class C extends
2 min read
React useEffectEvent

React useEffectEvent

在 React 最新的实验版中引入了一个新的 useEffectEvent hook, 引入这个新的 hook 出发点是为了解决下面场景中的问题: function View() { const [data, setData] = useState<{timestamp: number, value: any}>() const listener = useEffectEvent((newData) => { if (!data.timestamp || after(data.timestamp, 5min)) { setData(newData) } }) useEffect(() => { // effect to subscribe some remote data remote.subscribe('data', listener) return () => remote.unsubscribe() }, []) return (
{data}
) } 在 listener 中我
2 min read
读《Atomic Habits》

读《Atomic Habits》

最近公司同事组织了一个新的活动,Book Club, 大概就是选了一本书然后在本月的某天大家互相聊聊感想。我是出于增加自己的社交而加入的,而本期的书《Atomic Hobits》中文叫《原子习惯》刚好也是我加入书单没有阅读的书。 James 的理论概括起来以下4点: 1. 让你的爱好显而易见,比如你想去跑步,你就可以把你跑步的鞋、衣服等放在你视野范围内能够提醒你要去跑步了等,最重要的是持续,比如理论上你每天比昨天进步0.1 ,那么你一年内可以进步1.01^365 = 37.8 当然这是理论上的,现实里的完全做不到每天都进步 0.1 ,但是你在不断的进步。 2. 让你的爱好吸引人,当然这个“人“其实是吸引自己,如果你能够对你的爱好持续保持热情,那当然是最好的,但是有时候你也需要找到一些方法让这个爱好更吸引你,比如可以找到一个跑步伙伴一起跑等 3. 让你的爱好简单容易,如果你觉得每天跑步30分钟太难了,那是不是可以改成15分钟,甚至改成步行15分钟 4. 让你的爱好能够给你正面反馈,当你的爱好能够持续给你正面反馈的时候,你才会想要持续下去,但是大多数的时候你的爱好并不能给你带来
3 min read
OpenAI CEO 更迭记
杂文

OpenAI CEO 更迭记

前些日的 Open AI Inc. 公司的事件已经告一段落,Sam Altman 重新回到 OpenAI 任 CEO 而毫不意外的董事会重组。整个事情的经过颇俱戏剧性,而做为全球市值最大的 AI 创业公司同时也是AI 领域技术最先进的公司,这次的事情也足足吸引了全球网民的目光。 事情的经过此起彼伏,而做为看客的我们也过足了眼瘾。而事情的真相现在也几乎没有人再关心,各路社交媒体账号为了吸引眼球充斥着各种猜疑和阴谋论,他们最不关心的就是真相,尽是些什么首席科学家Ilya 过河拆桥,董事会成员Adam 兼Sam Altman 好友暗渡陈仓等等各种主观猜测。 那事情的真相是什么呢?我们无从知晓,可能当你明年读到一本关于OpenAI 员工的传记或者投资人的传记才会知道了吧。但是我所知道的是这个事情没有赢家,所有人都是输家。作为用户的我们,可能觉得 Sam Altman 回归是好事情,但是我们不禁会想这样一家世界最顶级的 AI 公司也会有这种 drama,也不过是另一类的草台班子,媒体大力营造的顶级公司形象一落千丈。做为 OpenAI 客户的企业客户和我这样的个人,会放心使用全体员工随时会愿意
3 min read
读《剪商》

读《剪商》

最近断断续续终于读完了李硕的《剪商》,这本书虽厚但是让人欲罢不能。此前对于商朝的理解只限于封神榜,和甲骨文的起源而已,对完整本书收益良多。之前也在网上看到这本书的作者因为胆管癌住院治疗有生命危险,万幸后来通过治疗顺利出院,也算是命途多舛。 商朝由于年代久远资料有限,外加政权交替造成的大量破坏,就算是古人对这些也知之甚少。比如“贞“字此前都是卜问的意思,直到近代发掘大量甲骨文后才重新定义是为一种类似巫师的职业。书中引述大量考古文献,分析商朝的祭祀文化,算得上一种残忍的宗教行为。商族作为中原士族中文明程度最高的族群对周围士族算是一种绝对的统治,青铜冶炼和文字,甲骨文中出现大量外出捕杀还处于原始阶段的部族的占卜。书中提到的甲骨文和祭祀文化的关系最让我感兴趣,祭祀活动属于商朝最重要的社会活动,所以才会有很多甲骨文的发明。比如,“卯“ 字就是形容将祭品的人或者动物从中破开等。 作者尝试解释商朝的覆灭是因为这种残忍的人祭导致的灭亡,所以才会有后面周公抹除所有商朝信息,导致整个文明的资料几乎覆灭。真相我们不得而知,而显而易见的是商朝的覆灭并不是姜子牙的功劳,末代商王帝辛(纣)也不是一个杀人为乐的
3 min read
配置管理
随笔

配置管理

最近偶尔在 X/Twitter 上看到有人讨论配置的管理。其中分别列举了macOS 的系统配置和 Kubeneters 的YAML 配置,关于是否GUI 就更好以下是我的一些看法: 讨论两个配置的好坏前,需要了解针你的 customer是谁,谁使用这些配置。 给 Kuberneters 提供GUI 去配置是否就能解决配置的复杂问题呢,我想并不一定能解决问题,反而会带来问题。比如一个robust 的服务或集群通常需要通过CI/CD 去构建,能够在出现问题的时候快速回滚到上一个版本。这种通过文件存储甚至是远程云端储存的优势就不言而喻了,无法想象在需要回滚的时候通过GUI 去恢复上一个版本的配置时有多大的信心。当然如果通过添加一些UI界面去提高配置/系统可读性,易于理解也未尝不可。 同样的让使用MacBook 的用户在连接 Wi-Fi 时需要找到系统配置文件添加代码然后等待软件重启,我想这可能是一台安装了 Ubuntu 的 MacBook。 简单而言只有适合配置方式没有错误的配置方式。
1 min read
将 Ghost 博客迁移到家里的 Raspberry PI
瞎折腾

将 Ghost 博客迁移到家里的 Raspberry PI

我这个博客最开始的时候使用的是 DigitalOcean 的最便宜的服务,后来 AWS 推出了更便宜每月 3 .5$ 的 LightSail ,我变把博客迁移到了 LightSail。由于博客本身使用的是 Docker 部署,博客使用的是 Ghost 的 self-hosted,只需使用 scp 将所有的数据从一台服务器拷贝到另外一台服务器即可。 scp [OPTIONS] [[user@]src_host:]file1 [[user@]dest_host:]file2 前几年我买了一块树莓派 4b, 心想着可以做一些好玩的事情,也可以把博客从 LightSail 迁移过来,每个月还可以节省一些钱,虽然很少但聊胜于无,遗憾的是一直没有行动。 刚这次假期的业余时间也很充沛,就刚好可以行动起来。迁移之前,我也研究了一下大概选择什么样的方案,我希望这个方案不单单可以用来部署我的博客也可以用来部署其他的一些应用。这时候 Coolify 进入了我眼前,这是一个类似于
5 min read
日本换驾照记
东京记事

日本换驾照记

在中国时我开车并不多,在上海的大部分时间居住都在公司 5 km 的范围内,相对于开车,地铁和自行车出行是个更好的选择。当然最关键的问题是我并没有一辆车,持有汽车的成本再算上使用次数也让我一直没有想法再买一辆。所以我的驾驶经验也并不丰富,这其中最长的一次就数有一年五一假期去山西自驾,租了一辆车几天的行程,两人平均开了 500 km 左右吧。 至于为什么想要换个日本驾照其实原因也很简单,总有很多地方是地铁没法到二公交又不方便的地方,再者就是我们还有一只宠物,有车出行也是方便很多。在来日本前,其实也已经做了一些功课,去哪里办理、需要哪些材料、哪些材料需要在国内办好等。准本的充足也是希望一切顺利。 到达日本后一直因为在处理其他更为紧急的事情,找一间公寓等,将这件事情放置一边,也正是因为如此也造成了我后面的一些问题。当然“懒“也是我一直没去办理的另外一个原因。大概几周前,我中国的驾照即将到期前,我终于不得不下定决心要去做这件事情。二月的早晨天还很冷,早晨 6 点多起床,天刚鱼肚白,几个月不曾早起的我们匆忙吃个烤吐司便直奔地铁站而去。经过一个多小时的车程终于抵达目的地,然后就是漫长的排队等待。
4 min read
涩谷十字路口

去日本工作

刚来日本时觉得每天时间都过的很慢,每天都有很多想去吃的餐厅、想去的地方、想做的事情,每一天都计划着下一天。不过 2 个多月过去以后好像习惯了新的生活节奏,时间眨眼即逝。 东京和上海,这两座东方最大的城市有些不一样,也有些相同的地方。在这之前最近一次来东京还是 3 年前,那还是世界还是正常的世界,没有疫情、没有战争、没有通货膨胀、没有健康码,有还是自由的国界。之前做为游客对东京的感觉是好吃的食物、干净街道、好玩的景点等等,和这次在东京工作的感觉也确实不一样,不用每天给自己安排满满的行程,因为也只有周末有空出去玩。作为游客不会日语会觉得很自然,工作在东京时却觉得语言的屏障让我降低了生活的质量。这次刚来东京时,日本政府还没有彻底开放国门,那时候几乎没有游客,都默认你会日语,当然也可能是因为同是黄色肤人,会觉得应该要会才对。当然也得庆幸,现在日本完全开放后,我可以做为看起来像游客的人得到更多包容。 在东京的工作和上海区别不大,去公司时便搭地铁去公司,在家办工时就宅在家中。东京的地铁更复杂,价格也稍微贵些,早高峰时也和上海一样拥挤。不过我更喜欢在公司工作,可以和同事没事的时候说说笑笑,谈谈一
4 min read