欢迎光临散文网 会员登陆 & 注册

react

2023-07-10 01:42 作者:Leezw-  | 我要投稿

在 Hook 出现后,React 的函式元件 (Function Component) 逐渐成为主流。关于函式元件,最常见的问题之一,便是「为什么 React 的函式元件需要是纯函式 (pure function)?」。本篇将以第一人称的方式,拟答这个问题。 什么是纯函式 (pure function)?

纯函式是指带有以下两个主要特点的函式,第一是「只要有相同的输入,就会有相同的输出」;第二则是它不会改变函式以外的存在,换句话说不会有副作用 (side effects)。 举例来说,f(x) = 2x 这个函式,只要输入的 x 是 1,输出的结果就会是 2;如果输入的 x 是 2,输出的就会是 4。不管呼叫多少次,输出都会是一样的,这就满足纯函式的第一个要件。相反地,假如函式当中有 Math.random() 这类随机性的运算,会让每次的输出不一定,就不能称为纯函式。 没有副作用,不改变函式以外的存在,则可以看到下面的例子 (推荐再回答这题时可以举例,会更好说明)。当本来在外的 guest 变数,因为 getCup 函式改变,我们就不能称 getCup 这个函式为纯函式。

let

guest

=

1

; function

sayHi

(message)

{ guest = guest +

1

;

return

`${message} 跟 ${guest} guests `; } 为什么 React 的函式元件需要是纯函式 (pure function)?

React 的函式元件之所以需要是纯函式,是因为当函式如果不纯 (impure),会让渲染出的画面不稳定,可能出现我们预期外的 UI 呈现。白话来说,就是比较容易造成 bugs。 如果每次的输入,会有不同的输出,那会让 UI 的呈现非常不稳定。以下面的程式码为例,如果我们想要依据客人的人数,来准备巧克力派的食材,当有随机数出现,每次传入的客人数相同,可能会有不同的食材数量,这假如出现在食谱网站,那会是很不理想的 bug。 function

ChocolatePie

({ guestNum })

{

const

milkNum

=

guestNum * Math.floor(Math.random() *

10

)

const

chocolateNum

=

guestNum *

2

return

(

加入 {milkNum} 杯牛奶,以及 {chocolateNum} 条巧克力
); }

// 如果实际渲染这三个元件,同样的 guestNum 会渲染出不同内容

3

} />

3

} />

3

} /> 如果有副作用,也将会造成不稳定的 bugs。以下面来自 React 官方范例的程式码来说,如果更动到了 Cup 元件外的 guest ,将会导致,即使渲染同一个 Cup 元件,却渲染出不同内容。这样的 bug 也是不理想的。

let

guest

=

0

; function

Cup

()

{

// Bad: changing a preexisting variable!

guest = guest +

1

;

return

Tea cup

for

guest #{guest}

; }

// 如果渲染下面这三个 Cup 元件,会有不同的结果

总结来说,当函式元件当中,有非纯函式的存在,就会不稳定有潜在的 bug;因此在写 React 的程式码时,我们尽可能地写纯函式。 延伸题:如何在 React 侦测不纯的函式?

在 React 常见的函式,除了函式元件,也有 setState、context 。在使用它们时,都要确保是纯函式。举例来说,如果作为输入传进去元件的 props,如果传入同样的 props 却有不同的结果,就会造成不稳定的 bugs。同样地,当我们要改变某个状态,如果直接去改变值,而不是 setState ,会造成副作用,这也会容易产生 bugs。 要在 React 避免不小心犯了这类错误,可以很简单地使用严格模式 (Strict Mode)。当我们开启严格模式后,React 在渲染每个元件时,都渲染两次;只要是不纯的函式,就很可能在两次渲染出现不同结果,这可以让我们更侦测出是哪里出问题。

react的评论 (共 条)

分享到微博请遵守国家法律