Live Note

Remain optimistic

useMemo

useMemo 是拿来保持一个对象引用不变的。useMemo 和 useCallback 都是 React 提供来做性能优化的。比起 classes, Hooks 给了开发者更高的灵活度和自由,但是对开发者要求也更高了,因为 Hooks 使用不恰当很容易导致性能问题。

假设有个 component,在 dataConfig 变化的时候重新去 fetchData:

1
2
3
4
5
6
<Child
fetchData={() => {
// fetch data
}}
dataConfig={{ id: getId(queryId) }}
/>

如果是个 Class Component,会这么写:

1
2
3
4
5
6
7
class Child extends React.Component<Props> {
componentWillReceiveProps(nextProps: Props) {
if (nextProps.dataConfig !== this.props.dataConfig) {
nextProps.fetchData(nextProps.dataConfig)
}
}
}

使用 Hooks 后长这样:

1
2
3
4
5
const Child = ({ fetchData, dataConfig }: Props) => {
useEffect(() => {
fetchData(dataConfig)
}, [fetchData, dataConfig])
}

使用 Class Component 时我们需要手动管理依赖,但是使用 Hooks 时会带来副作用:React 使用的是Object.is(),如果fetchData的 reference 变了,也会触发 useEffect
虽然逻辑上 React 的处理是合理的,但是还是需要手动去解决它导致的性能问题:官方提供了 useCallback 这个 hooks,用于解决函数引用问题。

Read more »

useRef

  • mutable ref
  • presist

eg: 实现一个需求:点击按钮时 input 自动聚焦。

  • createRef 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const HomePage = () => {
const input = createRef<HTMLInputElement>()

const handle = () => {
if (input.current) {
input.current.focus()
}
}

return (
<div>
<input ref={input} />
<button onClick={handle}>focus</button>
</div>
)
}
  • useRef 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const HomePage = () => {
const input = useRef<HTMLInputElement | null>(null)

const handle = () => {
if (input.current) {
input.current.focus()
}
}

return (
<div>
<input ref={input} />
<button onClick={handle}>focus</button>
</div>
)
}

两者的区别在于:createRef 每次渲染会返回一个新的引用,而 useRef 返回的是相同的引用(persist)。对于函数式组件,每次 useState 会造成整个组件的重新渲染,但是 uesRef 可以保证引用不变,不会触发 re-render。

Read more »

友好的 React Hooks

网络上对 react hooks 的评价负面大于正面,确实很容易写出性能有问题的代码,关键就在于:我们太喜欢用 useState 了。
在 vue-composition-api 中,reactivity 数据都有 wrapper,custom-vca 里不管产生多少个 reactivity 对象,不会直接产生 re-render。只有那些被 return 到外部跟 template 绑定的部分才会触发视图渲染。
而 react 的 reactivity 就是通过 re-render 实现的,useState 没有 wrapper,每次使用都会得到一个触发渲染的函数。在这种 reactivity 机制下,就需要特殊的方式编写 hooks —— State/Effect 分层

假设有个 useHeight:

1
const [ref, height] = useHeight()

高度变化时,被动 re-render,难以转换合并。大部分情况下,不提供 state,而提供 effect 可能会更好:

1
2
3
4
5
const [height, setHeight] = useState(0)
const ref = useHeight((height: number) => {
// do something
setHeight(height)
})

使用者在外部声明 state,然后在 callback 中按需 setState。使用者可以结合其他 state,做 dispatch 到 reducer 的一次整体更新,而不是被动 re-render。
根据 State/Effect 分层理念,尝试着给出友好地 react hooks 公式:

1
const handler = useProducer(consumer, options)

producer 接收 consumer callback 作为参数,返回 handler 控制函数,用于绑定到事件或其他位置。

Read more »

Mix-ins

Abstract subclasses or mix-ins are templates for classes. An ECMAScript class can only have a single superclass, so multiple inheritance from tooling classes, for example, is not possible. The functionality must be provided by the superclass.

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const calculatorMixin = (Base) =>
class extends Base {
calc() {
// do something
}
}

const randomizerMixin = (Base) =>
class extends Base {
remdomize() {
// do something
}
}

class Foo {}
class Bar extends calculatorMixin(randomizerMixin(Foo)) {}
const bar = new Bar()
console.log(bar.calc)
console.log(bar.remdomize) // also a function.

电影

  • ☑ 沐浴之王:老套路。看完了感觉很无聊。
  • ☑ Dead to 2020:英剧喜剧片。有点意思,照例黑老美。
  • ☑ 十诫:老电影,十分艺术。
  • ☑ Megan Leavey:军人与军犬之间的故事,但是我还是觉得一旦走上了这条路,就很难回归正常生活了。
  • ☐ 邪不压正
  • ☑ 急先锋:很难想象是 2020 年的电影,给我的感觉比不上神话。
  • ☑ Azizler(易舍难分):拿到了好的题材,拍了一部烂片。
  • ☑ Mosul(血战摩苏尔):钢枪很热血,剧情挺狗血。
  • ☑ Greenland(末日逃生):强行拖剧情,很多地方逻辑不通。特效还可以。
  • ☑ 赵子龙:垃圾片。
  • ☑ 送你一朵小红花
  • ☑ 盗梦空间

纪录片

  • ☑ Alien Worlds:根据现有的环境对其他星球进行模拟,幻想存在的物种。最后一集很震撼,随着进化只剩下神经系统,不需要肉体。靠葡萄糖维持生命,高度发达的机器人。

直接使用 su 权限移除镜像的 quarantine 标志

1
sudo xattr -rd com.apple.quarantine /Applications/<application-name>

转眼间就是新的一年了。

2020 年,庚子年。发生了许多事情。

  • 新冠
  • 澳洲大火
  • 美股熔断
  • ···

在这一年里我也毕业了,入职了,成为了一个打工人士。有了收入之后之前想买的东西都基本买齐了,之前想做的事还在稳步进行中。
虽然很多人说 2020 是未来十年中最好的一年,但是在我这还是有可圈可点的地方。大环境的改变,正是抓住机遇的时候。

Read more »