浅谈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 1.0.4 - New Wave Javascript(js源文件)
Jan 15 Javascript
Node.js中require的工作原理浅析
Jun 24 Javascript
JS实现图片产生波纹一样flash效果的方法
Feb 27 Javascript
json传值以及ajax接收详解
May 24 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
May 17 Javascript
JS去掉字符串前后空格、阻止表单提交的实现代码
Jun 08 Javascript
详解VueJS应用中管理用户权限
Feb 02 Javascript
浅谈如何优雅处理JavaScript异步错误
Nov 12 Javascript
Vue数据双向绑定原理实例解析
May 15 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
May 20 Javascript
浅谈JavaScript中你可能不知道URL构造函数的属性
Jul 13 Javascript
react antd实现动态增减表单
Jun 03 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
基于文本的搜索
2006/10/09 PHP
php类中private属性继承问题分析
2012/11/01 PHP
PHP实现统计在线人数功能示例
2016/10/15 PHP
详解PHP中foreach的用法和实例
2016/10/25 PHP
PHP实现小偷程序实例
2016/10/31 PHP
基于PHP的微信公众号的开发流程详解
2020/08/07 PHP
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
IFrame跨域高度自适应实现代码
2012/08/16 Javascript
JQuery的ready函数与JS的onload的区别详解
2013/11/21 Javascript
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
js获取会话框prompt的返回值的方法
2015/01/10 Javascript
原生js实现日期联动
2015/01/12 Javascript
JavaScript DOM事件(笔记)
2015/04/08 Javascript
基于jQuery实现仿微博发布框字数提示
2016/07/27 Javascript
详解Angular2 之 结构型指令
2017/06/21 Javascript
js判断文件类型大小并给出提示的实现方法
2018/01/03 Javascript
jQuery zTree树插件的使用教程
2019/08/16 jQuery
jquery实现拖拽添加元素功能
2020/12/01 jQuery
python django集成cas验证系统
2014/07/14 Python
深入理解python对json的操作总结
2017/01/05 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
Win10+GPU版Pytorch1.1安装的安装步骤
2019/09/27 Python
HTML5 LocalStorage 本地存储详细概括(多图)
2017/08/18 HTML / CSS
GAP欧盟网上商店:GAP EU
2016/09/13 全球购物
英国领先的狗和宠物美容专家:Christies Direct
2017/04/03 全球购物
英国和国际包裹递送:ParcelCompare
2019/08/26 全球购物
高考自主招生自荐信
2013/10/20 职场文书
2014年重阳节敬老活动方案
2014/09/16 职场文书
民主评议党员自我鉴定
2014/10/21 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
公司车队管理制度
2015/08/04 职场文书
老舍《猫》教学反思
2016/02/17 职场文书
Canvas跟随鼠标炫彩小球的实现
2021/04/11 Javascript
Python如何导出导入所有依赖包详解
2021/06/08 Python