优秀的的React开发者避开的五大常见失误


1. 避免内联定义React.memo

假如在memo包裹内直接采用箭头函数来定义组件,那么在React性能剖析工具中,这个组件将缺少明确的名称显示。

import { memo } from 'react' // 这会在剖析器中显示为'Anonymous' export const MyComponent = memo((props) => /* ... */)

取而代之的是,它会显现为“Anonymous”(匿名),这让我们难以辨识哪个组件导致了多余的渲染操作。

这种情况颇为不便,因为应用memo的目的往往是为了通过Profiler验证记忆化机制是否有效运转。

要规避此问题,可将组件独立定义到一个变量里:

const MyComponentInternal = (props) => /* ... */ // 这会在剖析器中显示为'MyComponent' export const MyComponent = memo(MyComponentInternal)

另外值得一提,若记忆化未被恰当运用,反而可能导致应用性能下降。每次渲染时比较props都需要开销,如果这些开销无法被省略的渲染所弥补,那么引入memo只会使程序运行更迟缓。

  1. 别在所有路由中重复同一错误边界

    假设你的应用包含多个页面,且每个页面都包裹了相同的错误边界组件,那么用户切换到其他页面时,错误界面不会自动清除。

    // 导航到另一页面时,错误画面仍会保留 <Route path="books" element={<ErrorBoundary><Books /></ErrorBoundary>} /> <Route path="users" element={<ErrorBoundary><Users /></ErrorBoundary>} /> <Route path="settings" element={<ErrorBoundary><Settings /></ErrorBoundary>} />

    原因在于React视这些错误边界为同一实例,因此导航视为组件更新,其内部错误状态得以保持。

    可以通过添加key属性来区分它们,从而解决问题:

    <Route path="books" element={<ErrorBoundary key="books"><Books /></ErrorBoundary>} /> <Route path="users" element={<ErrorBoundary key="users"><Users /></ErrorBoundary>} /> <Route path="settings" element={<ErrorBoundary key="settings"><Settings /></ErrorBoundary>} />

    或者,设计一个自定义错误边界组件,根据URL路径的基础名称设置内部key:

    const PageErrorBoundary = ({ children }) => {   const match = useMatch('*')   return <ErrorBoundary key={match.pathBasename}>{children}</ErrorBoundary> }
  2. 规避sort方法的变异特性

    sort函数会直接修改原数组。正如其他变异操作一样,这在React环境中容易引发多种缺陷。

    始终优先采用不可变更新方式。

    const items = [3, 1, 2] // 这会更改原始数组 items.sort((a, b) => a - b) console.log(items) // [1, 2, 3]

    若在状态数组上调用sort,而另一组件依赖其原始未排序序列,就可能导致意外错误。

    此外,如果在状态设置中这样操作:setItems(items.sort()),它不会触发更新,因为数组引用未变。

    作为替代,可利用不可变的toSorted方法,不过它在较旧浏览器中不可用。若需兼容旧版,可借助扩展运算符实现。

    return (   // 运用扩展运算符防止变异   [...items].sort((i1, i2) => i1.name.localeCompare(i2.name)) )

    需注意,如果在sort前先执行filter或map,这些方法会生成新数组,因此安全。只有直接对状态调用sort时才会出问题。

  3. 避免直接以0作为条件判断

    例如,在JavaScript中,你可能习惯编写这样的代码:

    {items.length && <List items={items} />}

    React会将数字渲染到界面上,因此如果列表长度为0,UI会显示一个'0'字符,而非预期地跳过渲染列表。

    可改为使用items.length > 0作为条件来防止此情况。

    {items.length && <List items={items} />} // 这会显示0 {items.length > 0 && <List items={items} />} // 这正常

    当然,也可采用双重否定运算符,如:

    {!!items.length && <List items={items} />}
  4. 优先选择useLayoutEffect而非useEffect

    useEffect并非在每次渲染后立即运行,而是等到DOM变更完成后稍作延迟才执行。这可能导致用户短暂瞥见应用处于中间状态的界面。

    这种延迟会引发不雅观的闪烁效果。

    相反,useLayoutEffect会在DOM更新后同步触发,从而确保在屏幕重绘前,用户始终看到最终一致的状态。

    因此,useLayoutEffect能有效消除闪烁。但对于非UI相关的副作用,如网络调用或事件监听器同步,使用useEffect已然足够。

最后

送人玫瑰,手留余香,觉得有收获的朋友可以点赞,关注一波 ,我们组建了高级前端交流群,如果您热爱技术,想一起讨论技术,交流进步,不管是面试题,工作中的问题,难点热点都可以在交流群交流,为了拿到大Offer,邀请您进群,入群就送前端精选100本电子书以及 阿里面试前端精选资料 添加 下方小助手二维码或者扫描二维码 就可以进群。让我们一起学习进步.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值