浅谈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中的pushStack实现原理和应用实例
Feb 03 Javascript
值得分享的Bootstrap Ace模板实现菜单和Tab页效果
Dec 30 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
Jun 21 Javascript
Highcharts入门之简介
Aug 02 Javascript
JavaScript获取服务器时间的方法详解
Dec 11 Javascript
JS实现获取来自百度,Google,soso,sogou关键词的方法
Dec 21 Javascript
关于vue.js发布后路径引用的问题解决
Aug 15 Javascript
JavaScript使用math.js进行精确计算操作示例
Jun 19 Javascript
使用JavaScript破解web
Sep 28 Javascript
async/await让异步操作同步执行的方法详解
Nov 01 Javascript
JavaScript实现Excel表格效果
Feb 07 Javascript
vue组件中节流函数的失效的原因和解决方法
Dec 02 Vue.js
微信小程序实现顶部下拉菜单栏
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
一个连接两个不同MYSQL数据库的PHP程序
2006/10/09 PHP
PHP 模拟登陆MSN并获得用户信息
2009/05/16 PHP
完整显示当前日期和时间的JS代码
2007/09/17 Javascript
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
JQuery动画和停止动画实例代码
2013/03/01 Javascript
JS中setTimeout()的用法详解
2013/04/14 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
学习JavaScript编程语言的8张思维导图分享
2015/03/27 Javascript
javascript实现漂亮的拖动层,窗口拖拽特效
2015/04/24 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
jQuery实现边框动态效果的实例代码
2016/09/23 Javascript
jQuery.uploadify文件上传组件实例讲解
2016/09/23 Javascript
JavaScript创建对象_动力节点Java学院整理
2017/06/27 Javascript
微信通过页面(H5)直接打开本地app的解决方法
2017/09/09 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
JS实现碰撞检测的方法分析
2018/01/19 Javascript
小程序实现左滑删除功能
2018/10/30 Javascript
分享Angular http interceptors 拦截器使用(推荐)
2019/11/10 Javascript
深入浅析JavaScript中的in关键字和for-in循环
2020/04/20 Javascript
[33:15]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VP VS Mineski
2018/03/31 DOTA
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
Python实现的选择排序算法示例
2017/11/29 Python
python实现随机漫步算法
2018/08/27 Python
python 获取一个值在某个区间的指定倍数的值方法
2018/11/12 Python
python+selenium 鼠标事件操作方法
2019/08/24 Python
Python 字符串类型列表转换成真正列表类型过程解析
2019/08/26 Python
使用Tkinter制作信息提示框
2020/02/18 Python
简单了解python shutil模块原理及使用方法
2020/04/28 Python
Keras loss函数剖析
2020/07/06 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
电大本科自我鉴定
2014/02/05 职场文书
钳工实训报告总结
2014/11/04 职场文书
中学生学习保证书
2015/02/26 职场文书
心术观后感
2015/06/11 职场文书
高中数学教学反思范文
2016/02/18 职场文书
2016年党员承诺书范文
2016/03/24 职场文书