浅谈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 相关文章推荐
jQuery Lightbox 图片展示插件使用说明
Apr 25 Javascript
JavaScript获取当前页面上的指定对象示例代码
Feb 28 Javascript
ajaxFileUpload.js插件支持多文件上传的方法
Sep 02 Javascript
JavaScript实现关键字高亮功能
Nov 12 Javascript
jQuery实现简单二级下拉菜单
Apr 12 Javascript
将form表单通过ajax实现无刷新提交的简单实例
Oct 12 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
Oct 26 Javascript
bootstrap table配置参数例子
Jan 05 Javascript
原生js实现电商侧边导航效果
Jan 19 Javascript
详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)
Apr 09 Javascript
基于Bootstrap和JQuery实现动态打开和关闭tab页的实例代码
Jun 10 jQuery
在JavaScript中使用严格模式(Strict Mode)
Jun 13 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 fsockopen中多线程问题的解决办法[翻译]
2011/11/09 PHP
apache php模块整合操作指南
2012/11/16 PHP
如何让thinkphp在模型中自动完成session赋值小教程
2014/09/05 PHP
实例讲解PHP设计模式编程中的简单工厂模式
2016/02/29 PHP
PHP图像识别技术原理与实现
2016/10/27 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
学习面向对象之面向对象的基本概念:对象和其他基本要素
2010/11/30 Javascript
关于extjs4如何获取grid修改后的数据的问题
2013/08/07 Javascript
页面js遇到乱码问题的解决方法是和无法转码的情况
2014/04/30 Javascript
js Object2String方便查看js对象内容
2014/11/24 Javascript
js实现可得到不同颜色值的颜色选择器实例
2015/02/28 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
JS实现的打字机效果完整实例
2016/06/20 Javascript
Vue.js每天必学之内部响应式原理探究
2016/09/07 Javascript
JavaScript实现前端分页控件
2017/04/19 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
ES6小技巧之代替lodash
2019/06/07 Javascript
bootstrap Table实现合并相同行
2019/07/19 Javascript
jquery绑定事件 bind和on的用法与区别分析
2020/05/22 jQuery
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
[03:40]DOTA2抗疫特别篇《英雄年代》
2020/02/28 DOTA
python读取json文件并将数据插入到mongodb的方法
2015/03/23 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
2020/06/01 Python
如何学习Python time模块
2020/06/03 Python
美国半成品食材配送服务商:Home Chef
2018/01/25 全球购物
英国50岁以上人群的交友网站:Ourtime
2018/03/28 全球购物
彪马土耳其官网:PUMA土耳其
2019/07/14 全球购物
PHP如何与mysql建立链接
2013/05/05 面试题
优秀教师主要事迹
2014/02/01 职场文书
大学生自我鉴定书
2014/03/24 职场文书
政府绩效管理实施方案
2014/05/04 职场文书
售后客服个人自我评价
2014/09/14 职场文书
公司表扬信格式
2015/05/04 职场文书
幼儿园推普周活动总结
2015/05/07 职场文书