浅谈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 相关文章推荐
Javascript技术技巧大全(五)
Jan 22 Javascript
在textarea中显示html页面的javascript代码
Apr 20 Javascript
编辑浪子版表单验证类
May 12 Javascript
关于JS中的闭包浅谈
Aug 23 Javascript
Javascript中的五种数据类型详解
Dec 26 Javascript
jQuery中:not选择器用法实例
Dec 30 Javascript
深入分析jsonp协议原理
Sep 26 Javascript
jQuery实现级联下拉框实战(5)
Feb 08 Javascript
angular4笔记系列之内置指令小结
Nov 09 Javascript
微信提示 在浏览器打开 效果实现过程解析
Sep 10 Javascript
vue+openlayers绘制省市边界线
Dec 24 Vue.js
JS前端使用canvas实现扩展物体类和事件派发
Aug 05 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
星际争霸任务指南——虫族
2020/03/04 星际争霸
跟我学小偷程序之成功偷取首页(第三天)
2006/10/09 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
2014/11/17 PHP
PHP中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别分析
2017/07/03 PHP
PHP实现登陆并抓取微信列表中最新一组微信消息的方法
2017/07/10 PHP
PHP使用PDO、mysqli扩展实现与数据库交互操作详解
2019/07/20 PHP
固定表格行列(expression)在IE下适用
2013/07/25 Javascript
Jquery全选与反选点击执行一次的解决方案
2015/08/14 Javascript
javascript跨域总结之window.name实现的跨域数据传输
2015/11/01 Javascript
javascript字符串对象常用api函数小结(连接,替换,分割,转换等)
2016/09/20 Javascript
JS声明式函数与赋值式函数实例分析
2016/12/13 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
canvas+gif.js打造自己的数字雨头像的示例代码
2017/10/26 Javascript
微信小程序自定义对话框弹出和隐藏动画
2018/07/19 Javascript
JavaScript闭包原理与用法实例分析
2018/08/10 Javascript
node.js爬取中关村的在线电瓶车信息
2018/11/13 Javascript
小程序从手动埋点到自动埋点的实现方法
2019/01/24 Javascript
Vue渲染过程浅析
2019/03/14 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
2019/09/27 jQuery
vue-devtools的安装和使用步骤详解
2019/10/17 Javascript
Python随机生成手机号、数字的方法详解
2017/07/21 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
python+selenium识别验证码并登录的示例代码
2017/12/21 Python
在python下读取并展示raw格式的图片实例
2019/01/24 Python
Python面向对象进阶学习
2019/05/21 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
20行Python代码实现视频字符化功能
2020/04/13 Python
如何基于python实现不邻接植花
2020/05/01 Python
Levi’s西班牙官方网站:李维斯,著名的牛仔裤品牌
2020/08/20 全球购物
恐龙的灭绝教学反思
2014/02/12 职场文书
先进员工获奖感言
2014/08/14 职场文书
中学生秋季运动会广播稿
2014/09/21 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
初中英语教学反思范文
2016/02/15 职场文书
MySQL GRANT用户授权的实现
2021/06/18 MySQL