浅谈React碰到v-if


Posted in Javascript onNovember 04, 2018

最近在重构公司老项目,由于本人以前的技术栈是vue, 换工作后发现现在公司的技术栈是react, 所以重构的过程是及其痛苦。加之项目又是几年前的老项目,不敢大改,比葫芦画瓢比比皆是。本文就介绍下遇到的一个常用的痛点。欢迎大佬指正。

废话不多说,直接上一段代码。

import React from 'react'

const App = () => {
 const record = {
  toKe: true, // 贝壳首页
  toSecondHand: true, // 二手房
  toFang: true, // 新房
 }
 return (
  <div style={{width: 600, margin: '50px auto'}}>
   <ul>
    <li>
     <h3>react常规写法</h3>
     {
      record.toKe
      ? <a style={{padding: 20}} href="https://bj.ke.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >贝壳首页</a>
      : null
     }
     {
      record.toSecondHand
      ? <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
      : null
     }
     {
      record.toFang
      ? <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
      : null
     }
    </li>
   </ul>
  </div>
 )
}
export default App

如上述代码,我们在项目中会遇到很多这样的写法, 细看一下没什么问题,可是当在重构老项目的时候,你会发现这个代码结构是多么痛苦,特别是如下的结构。

{
  record.toFang && record.toKe && record.toSecondHand
  && <div>
    <a style={{padding: 20}} href="https://bj.ke.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >贝壳首页</a>
    <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
    <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
  </div>
}

虽然代码逻辑没问题,但人生就是这样,有时候出场顺序真的很重要。突然就想起vue的v-if了。
没错,回归主题,就是:react中模拟vue的v-if

先上代码

import React from 'react'
import Hidden from './Hidden'
const App = () => {
 const record = {
  toKe: true, // 贝壳首页
  toSecondHand: true, // 二手房
  toFang: true, // 新房
 }
 return (
  <div style={{width: 600, margin: '50px auto'}}>
   <ul>
    <li>
     <h3>react模拟实现vue中v-if指令</h3>
     <Hidden visible={record.toKe} tag='span'>
      <a href="https://bj.ke.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >贝壳首页</a>
     </Hidden>
     <Hidden visible={record.toSecondHand} tag='span' style={{padding: 20}}>
      <a href="https://bj.ke.com/ershoufang/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
     </Hidden>
     <Hidden visible={record.toFang} tag='p'>
      <a href="https://bj.fang.ke.com/loupan/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
     </Hidden>
    </li>
   </ul>
  </div>
 )
}
export default App

简单就是封装Hidden组件,通过visible去控制是否渲染。

相信聪明的你一定知道怎么去封装Hidden

笔者刚开始是这么写的

import React, { Component } from 'react'

export default class Hidden extends Component {
 render() {
  const { visible, children } = this.props
  const content = visible ? children : null
  return (
   <div>
    { content }
   </div>
  )
 }
}

如此简单,但笔者审查元素的时候发现,每个Hidden下的children莫名被嵌套了一层div

如下

浅谈React碰到v-if

原来的横着排列的元素,一下子竖着排列了。这可不太好,本来给我套个div,我都可以勉强接收,现在连我布局都给我变了。
怎么办?笔者突然想到使用vue-router中的router-link时,标签是可以通过tag去替换默认标签的。

那我们再给它个tag呗,连带自定义属性。

import React, { Component } from 'react'

export default class Hidden extends Component {
 render() {
  const { visible, children, tag = 'div', ...rest } = this.props
  const content = visible ? children : null
  return (
   React.createElement(tag, rest, content)
  )
  // return (
  // 尝试用这种方法去实现,发现不符合react的规则,所以使用最原始的渲染方法
  // React.createElement
  // `<`${tag}`>` + { content } + `</`${tag}`>` 
  // )
 }
}

问题:笔者的初衷是模拟vue的v-if, 所以对传入的children并没做太多处理,不建议做多做封装。有兴趣的同学可以自己玩。

{
  record.toFang && record.toKe && record.toSecondHand
  && <span>
    <a style={{padding: 20}} href="https://bj.ke.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >贝壳首页</a>
    <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
    <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
  </span>
}
<Hidden 
  visible={record.toFang && record.toKe && record.toSecondHand} 
  tag='span'>
  a href="https://bj.ke.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >贝壳首页</a>
  <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
  <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
</Hidden>

其实感觉也没多大用处hhhh

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js Map List 遍历使用示例
Jul 10 Javascript
jQuery实现的网格线绘制方法
Jun 20 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
Oct 27 Javascript
jQuery中$.grep() 过滤函数 数组过滤
Nov 22 Javascript
js实现交通灯效果
Jan 13 Javascript
BootStrap fileinput.js文件上传组件实例代码
Feb 20 Javascript
JS封装的模仿qq右下角消息弹窗功能示例
Aug 22 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
May 13 Javascript
vue各种事件监听实例(小结)
Jun 24 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
Sep 02 Javascript
OpenLayers3实现图层控件功能
Sep 25 Javascript
解决Vue watch里调用方法的坑
Nov 07 Javascript
微信小程序实现顶部下拉菜单栏
Nov 04 #Javascript
微信小程序使用template标签实现五星评分功能
Nov 03 #Javascript
基于Vue-cli快速搭建项目的完整步骤
Nov 03 #Javascript
微信小程序实现笑脸评分功能
Nov 03 #Javascript
小程序实现五星点评效果
Nov 03 #Javascript
微信小程序实现星星评价效果
Nov 02 #Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
Nov 02 #Javascript
You might like
php实现mysql数据库操作类分享
2014/02/14 PHP
php实现以只读方式打开文件的方法
2015/03/16 PHP
php计算给定时间之前的函数用法实例
2015/04/03 PHP
PHP生成静态HTML页面最简单方法示例
2015/04/09 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
JS getAttribute和setAttribute(取得和设置属性)的使用介绍
2013/07/10 Javascript
Jquery中find与each方法用法实例
2015/02/04 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
AngularJS模仿Form表单提交的实现代码
2016/12/08 Javascript
Ajax基础知识详解
2017/02/17 Javascript
jQuery日程管理控件glDatePicker用法详解
2017/03/29 jQuery
vue如何集成raphael.js中国地图的方法示例
2017/08/15 Javascript
vue实现长图垂直居上 vue实现短图垂直居中
2017/10/18 Javascript
JavaScript基于数组实现的栈与队列操作示例
2018/12/22 Javascript
layui实现根据table数据判断按钮显示情况的方法
2019/09/26 Javascript
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
python获取标准北京时间的方法
2015/03/24 Python
Windows系统下使用flup搭建Nginx和Python环境的方法
2015/12/25 Python
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
Python实现列表删除重复元素的三种常用方法分析
2017/11/24 Python
Python 获取windows桌面路径的5种方法小结
2019/07/15 Python
Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例
2020/03/14 Python
Whittard官方海外旗舰店:英国百年茶叶品牌
2018/02/22 全球购物
大学生职业规划论文
2014/01/11 职场文书
安全生产责任书范本
2014/04/15 职场文书
迎新生标语大全
2014/10/06 职场文书
2014年工程部工作总结
2014/11/25 职场文书
画展邀请函
2015/01/31 职场文书
创业计划书之书店
2019/09/10 职场文书
Python数据清洗工具之Numpy的基本操作
2021/04/22 Python
GitHub上77.9K的Axios项目有哪些值得借鉴的地方详析
2021/06/15 Javascript
MySQL Server层四个日志的实现
2022/03/31 MySQL
SpringBoot整合minio快速入门教程(代码示例)
2022/04/03 Java/Android
vue3引入highlight.js进行代码高亮的方法实例
2022/04/08 Vue.js
如何更改Win11声音输出设备?Win11声音输出设备四种更改方法
2022/04/08 数码科技
mysql查找连续出现n次以上的数字
2022/05/11 MySQL