关于React你必须知道的3个错误用法。

news2024/9/22 4:14:25

1. 你知道如何使用“&&”吗?

在React程序中,我经常使用“&&”运算符来决定是否显示内容,如下所示:

我的组长: “你不知道&&运算符的特性吗?当请求还没有成功返回时,会直接渲染“0”。”

我并不信服, 因为我一直都是这样编写代码,从未出过错。为了证明老板错了,我写了下面的示例

我的天!组长是对的,页面开始是显示0,3秒后才显示列表。

为什么?

提示(来自 MDN):“逻辑与(&&)运算符(逻辑连词)对一组布尔操作数将只有当所有操作数都为真时才为真。否则,它将为假。”

更一般地说,该运算符返回从左到右评估时遇到的第一个假值操作数的值,或者如果它们都是真值,则返回最后一个操作数的值。

几个例子

const x1 = 0
const x2 = 'fatfish'
const x3 = 1
const x4 = 'medium'
console.log(x1 && x2) // 0
console.log(x3 && x4) // medium

现在我终于理解为什么那样编写代码会导致错误了。原因如下:

list.length && <List list={ list } /> 
0 && <List list={ list } /> // 0

如何解决?

我找到了三种解决这个问题的方法。希望你不要犯我的错误。祝你好运。

// 1. Convert list.length to boolean
!!list.length && <List list={ list }/>
  
// 2. Use ternary expressions and null
list.length ? <List list={ list }/> : null

// 3. Controlled by specific logic
list.length >= 1 && <List list={ list }/>

2. “props.children”的奇怪行为

我猜你写过类似的代码。 当向<Container />组件传递内容时,“children” 将显示。如果没有,将显示一个空工具提示。 如下所示:

const Container = ({ children }) => {
  if (children) {
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}

我的老板:“你必须谨慎使用“children”属性,它会导致逻辑异常!像下面这种情况。”

1. 空列表数据

你认为这个例子会显示什么——“空”?

不幸的是,答案是另一个。 朋友们,我们必须非常小心地使用 props.children。 否则,老板可能会扣掉你的工资。

const Container = ({ children }) => {
  if (children) {
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}
const App = () => {
  const [ list, setList ] = React.useState([])
  
  return (
    <Container>
      {
        list.map((name) => {
          return <div className="name-item">{ name }</div>  
        })
      }
    </Container>
  )
}
ReactDOM.render(<App />, document.getElementById('app'))

为什么?

让我们在“Container”组件中添加一行代码,并尝试打印children是什么!

const Container = ({ children }) => {
  console.log(children, 'children')
  // ...
}

是的,你猜对了。 此时,“children”是一个空数组,所以显示“children的内容是:”而不是“空”

如何解决?

使用 React.Children.toArray 来解决这个问题将非常容易,然后你会看到显示“空”。 所以,如果你真的需要将子代用作条件判断,我建议你使用这种方法!

const Container = ({ children }) => {
  // if (children) {
  // Pay attention here
  if (React.Children.toArray(children).length) {  
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}

3. 关于挂载和更新的问题

在React中通过状态切换组件是很常见的,但这个小东西也会让你困惑。

在下面的代码中,当你切换 name 的值时,你认为一个 Demo 组件将被卸载并且另一个将被挂载吗?

lass Demo extends React.Component {
  componentDidMount() {
    console.log('componentDidMount', this.props.name);
  }
  componentDidUpdate() {
    console.log('componentDidUpdate', this.props.name);
  }
  
  render () {
    return (
      <div>
        { this.props.name }
      </div>
    )
  }
}
const App = () => {
  const [ name, setName ] = React.useState('fatfish')
  const onClick = () => {
    setName(name === 'fatfish' ? 'medium' : 'fatfish')
  }
  return (
    <div className="app">
      {
        name === 'fatfish' ? 
          <Demo name={ name } /> : 
          <Demo name={ name } />
      }
      <button onClick={ onClick }>click</button>
    </div>
  )
}
ReactDOM.render(<App />, document.getElementById('app'))

我录制了一个短gif来给你真相,你也可以通过 CodePen 尝试它。

为什么?

尽管我们写了两个 Demo 组件并且假设它们会分别挂载和更新,但 React 认为它们是相同的组件,所以 componentDidMount 只会执行一次。

如何解决?

但是当我们想写两个相同的组件但传递不同的参数时,我们该怎么做呢?

是的,你应该给这两个组件添加不同的 ‘keys’,这样 React 会认为它们是不同的组件。componentDidMount 也会各自执行。

让我们试试

//...
// Pay attention here
name === 'fatfish' ? <Demo key="1" name={ name } /> : <Demo key="2" name={ name } />
//...

最后

感谢阅读。 期待你的关注和高质量文章。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381429.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp怎么开发插件并发布

今天耳机坏了,暂时内卷不了,所以想开发几个插件玩玩,也好久没写博客了,就拿这个来写了 首先,发布插件时需要你有项目 这里先拿uniapp创建一个项目, 如下,创建好的项目长这样 然后根据uniapp官网上说的,我们发布插件时,需要在uni_modules里面编写和发布 ps:还需要使用uniapp…

OpenWrt智能路由器Wan PPPoE拨号配置方法

OpenWrt智能路由器的wan PPPoE拨号配置方法和我们常见的不太一样, 需要先找到wan网卡,然后将协议切换为 PPPoE然后才能看到输入上网账号和密码的地方. 首先登录路由器 http://openwrt.lan/ 然后找到 Network --> Interfaces 这里会显示你当前的路由器的所有接口, 选择 …

代码随想录算法训练营第七天|哈希表理论基础,454.四数相加II ,383. 赎金信 ,15. 三数之和 ,18. 四数之和

刷题建议 刷题建议与debug 代码随想录目前基本都有了视频讲解&#xff0c;一定要先看视频&#xff0c;事半功倍。写博客&#xff0c;将自己的感悟沉淀下来&#xff0c;不然会忘大家提问的时候&#xff0c;记得要把问题描述清楚&#xff0c;自己在哪一步遇到了问题&#xff0c…

(学习日记)2024.01.09

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

5V高细分步进电机驱动芯片选型分析

单通道5V高细分步进电机GC6139 GC6106 GC6107 GC6119 GC6151 GC6236 GC8558 它们应用在摇头机&#xff0c;X,Y控制&#xff0c;聚焦控制等产品上。其中GC8558为24V H 桥驱动&#xff0c;大电流&#xff0c;具有短地短电源保护&#xff0c;限流保护等功能。

qt学习:多界面跳转+信号+槽函数

目录 概念 分类 多界面编程思路 新建界面 注意 头文件 无数据传输跳转界面 有数据传输跳转界面 对象公有接口 界面之间数据传输 信号与槽函数进行数据传输跳转界面 信号: 槽: 概念 格式1 关联信号和发送信号 格式2 通信步骤 自定义信号和槽函数 总结 实…

C++/WinRT 入门

本主题将会根据新的 Windows 控制台应用程序 (C/WinRT) 项目演练一个简单的代码示例。 C/WinRT 快速入门 创建一个新的 Windows 控制台应用程序(C/WinRT) 项目。 根据实际选择平台 如果出现如下错误&#xff0c;需要安装正确的SDK。 找不到 Windows SDK 版本 10.0.17134.0 (o…

Seata TM管理分支事务源码

TM相当于一个中间商&#xff0c;是没有涉及到任何数据库底层操作的。 TransactionalTemplate 1、TM向TC端发起一次开启全局事务的请求 io.seata.tm.api.TransactionalTemplate#beginTransaction --> io.seata.tm.api.DefaultGlobalTransaction#begin(int, java.lang.Strin…

scroll-view在小程序页面里实现滚动,uniapp项目

要实现红框中的区域进行滚动,scroll-view必须写高 <template><!-- 合同-待确认 --><view class"viewport"><!-- 上 --><view class"top-box"><!-- tab --><view class"tabs"><textv-for"(ite…

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力…

Fabric2.2:在有系统通道的情况下搭建应用通道

写在最前 在使用Fabric-SDK-Go1.0.0操作Fabric网络时遇到了bug。Fabric-SDK-GO的当前版本没有办法在没有系统通道的情况下创建应用通道&#xff0c;而Fabric的最新几个版本允许在没有系统通道的情况下搭建应用通道。为了解决这个矛盾并使用Fabric-SDK-GO完成后续的项目开发&…

Hive命令行运行SQL将数据保存到本地如何去除日志信息

1.场景分析 先有需求需要查询hive数仓数据并将结果保存到本地&#xff0c;但是在操作过程中总会有日志信息和表头信息一起保存到本地&#xff0c;不符合业务需要&#xff0c;那如何才能解决该问题呢&#xff1f; 废话不多少&#xff0c;直接上代码介绍&#xff1a; 2.问题解决…

HarmonyOS应用开发学习笔记 arkTS自定义弹窗(CustomDialog)简单使用 arkTS弹出框回调、监听

HarmonyOS应用开发学习笔记 arkTS自定义弹窗&#xff08;CustomDialog&#xff09;简单使用 1、CustomDialog装饰器用于装饰自定义弹框 1、定义弹出框 CustomDialog CustomDialog export struct CustomDialogExample {controller: CustomDialogControllerbuild() {Column() {…

基于反卷积方法的重大突破:结构光系统中的测量误差降低3倍

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 结构光三维测量技术在工业自动化、逆向工程和图形学领域越来越受欢迎。然而&#xff0c;现有的测量系统在成像过程中存在不完美&#xff0c;会导致在不连续边缘周…

Nacos注册中心-安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、认识Nacos二、安装Nacos1.直接方法nacos.io&#xff0c;点击view onGithub2.点击Releases3、点击Tags&#xff0c;可以看见所有版本&#xff0c;建议下载1.…

Linux 系统编程:文件系统的底层逻辑 - inode

《Linux 程序设计》的第三章讲文件操作。在提到 目录 时有这么一段文字&#xff1a; 文件&#xff0c;除了本身包含的 内容 以外&#xff0c;它还会有一个 名字 和一些 属性&#xff0c;即“管理信息”&#xff0c;包括文件的创建 / 修改日期和它的访问权限。这些属性被保存在文…

【LabVIEW FPGA入门】使用CompactRIO进行SPI和I2C通信

NI提供了 SPI and I2C Driver API&#xff1a;下载SPI and I2C Driver API - NI 该API使用FPGA数字I / O线与SPI或I2C设备进行通信。 选择数字硬件时&#xff0c;要考虑三个选项&#xff1a; NI Single-Board RIO硬件可同时使用SPI和I2C驱动程序。NI 9401 C系列模块与SPI驱动程…

阅读文献-胃癌

写在前面 今天先不阅读肺癌的了&#xff0c;先读一篇胃癌的文章 文献 An individualized stemness-related signature to predict prognosis and immunotherapy responses for gastric cancer using single-cell and bulk tissue transcriptomes IF:4.0 中科院分区:2区 医学…

用通俗易懂的方式讲解:大模型微调方法总结

大家好&#xff0c;今天给大家分享大模型微调方法&#xff1a;LoRA,Adapter,Prefix-tuning&#xff0c;P-tuning&#xff0c;Prompt-tuning。 文末有大模型一系列文章及技术交流方式&#xff0c;传统美德不要忘了&#xff0c;喜欢本文记得收藏、关注、点赞。 文章目录 1、LoRA…

vivado 指定顶部模块和重新排序源

指定顶部模块和重新排序源 文件夹默认情况下&#xff0c;Vivado Design Suite会自动确定设计的顶层添加到的源文件的层次结构和细化、合成和模拟的顺序项目这可以通过右键单击中的“层次更新”设置进行控制“源”窗口的菜单。请参阅中的“源”窗口中的“层次更新”命令Vivado …