浅谈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 相关文章推荐
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
Aug 28 Javascript
js用Date对象处理时间实现思路及代码
Jan 31 Javascript
javascript弹出层输入框(示例代码)
Dec 11 Javascript
javascript调试之DOM断点调试法使用技巧分享
Apr 15 Javascript
使用jquery 简单实现下拉菜单
Jan 14 Javascript
解决Window10系统下Node安装报错的问题分析
Dec 13 Javascript
vue语法之拼接字符串的示例代码
Oct 25 Javascript
Vuepress 搭建带评论功能的静态博客的实现
Feb 17 Javascript
微信小程序实现签字功能
Dec 23 Javascript
使用JavaScript通过前端发送电子邮件
May 22 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
Nov 16 Javascript
详解vue中v-for的key唯一性
May 15 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
VML绘图板②脚本--VMLgraph.js、XMLtool.js
2006/10/09 PHP
php报表之jpgraph柱状图实例代码
2011/08/22 PHP
php变量作用域的深入解析
2013/06/03 PHP
基于php常用函数总结(数组,字符串,时间,文件操作)
2013/06/27 PHP
在PHP中使用redis
2013/11/04 PHP
PHP Oauth授权和本地加密实现方法
2016/08/12 PHP
Ubuntu上安装yaf扩展的方法
2018/01/29 PHP
jquery键盘事件使用介绍
2011/11/01 Javascript
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
JS提交form表单实例分析
2015/12/10 Javascript
BootStrap实用代码片段之一
2016/03/22 Javascript
AngularJs 弹出模态框(model)
2016/04/07 Javascript
TinyMCE汉化及本地上传图片功能实例详解
2016/05/31 Javascript
深入理解jQuery layui分页控件的使用
2016/08/17 Javascript
javascript匀速动画和缓冲动画详解
2016/10/20 Javascript
浅述Javascript的外部对象
2016/12/07 Javascript
vue proxyTable 接口跨域请求调试的示例
2017/09/12 Javascript
Vue 用Vant实现时间选择器的示例代码
2019/10/25 Javascript
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
浅谈利用numpy对矩阵进行归一化处理的方法
2018/07/11 Python
python 读写文件,按行修改文件的方法
2018/07/12 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
2020/10/02 Python
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
巴西最大的珠宝连锁店:Vivara
2019/04/18 全球购物
电气个人求职信范文
2014/02/04 职场文书
亮剑精神演讲稿
2014/05/23 职场文书
试用期转正员工自我评价
2014/09/18 职场文书
检察院起诉书
2015/05/20 职场文书
导游词之鲁迅祖居
2019/10/17 职场文书
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB
Kubernetes部署实例并配置Deployment、网络映射、副本集
2022/04/01 Servers
tomcat正常启动但网页却无法访问的几种解决方法
2022/05/06 Servers
windows10 家庭版下FTP服务器搭建教程
2022/08/05 Servers