浅谈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 相关文章推荐
js 关于=+与+=日期函数使用说明(赋值运算符)
Nov 15 Javascript
jQuery使用之处理页面元素用法实例
Jan 19 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
Mar 27 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
Oct 19 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
May 31 Javascript
精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
Jul 01 Javascript
js图片轮播手动切换特效
Jan 12 Javascript
vue实现前进刷新后退不刷新效果
Jan 26 Javascript
vue项目中vue-i18n和element-ui国际化开发实现过程
Apr 25 Javascript
解决vue-cli3 使用子目录部署问题
Jul 19 Javascript
vue组件之间数据传递的方法实例分析
Feb 12 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 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
提升PHP执行速度全攻略(下)
2006/10/09 PHP
PHP memcache扩展的三种安装方法
2009/04/26 PHP
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
KindEditor在php环境下上传图片功能集成的方法示例
2020/07/20 PHP
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
asp.net 30分钟掌握无刷新 Repeater
2011/09/16 Javascript
JS,Jquery获取select,dropdownlist,checkbox下拉列表框的值(示例代码)
2014/01/11 Javascript
基于jquery的simpleValidate简易验证插件
2014/01/31 Javascript
jquery中validate与form插件提交的方式小结
2016/03/26 Javascript
vue.js轮播图组件使用方法详解
2018/07/03 Javascript
angular6的响应式表单的实现
2018/10/10 Javascript
移动端图片上传旋转、压缩问题的方法
2018/10/16 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
2018/11/21 Javascript
js时间转换毫秒的实例代码
2019/08/21 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
2020/06/02 Javascript
[01:54]TI4西雅图DOTA2选手欢迎晚宴 现场报道
2014/07/08 DOTA
Python实现简单字典树的方法
2016/04/29 Python
Python字典创建 遍历 添加等实用基础操作技巧
2018/09/13 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
详解Python中的路径问题
2020/09/02 Python
pytorch 移动端部署之helloworld的使用
2020/10/30 Python
CSS3实现多样的边框效果
2018/05/04 HTML / CSS
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
Html5移动端网页端适配(js+rem)
2021/02/03 HTML / CSS
木工主管岗位职责
2013/12/08 职场文书
学习经验交流会主持词
2014/04/01 职场文书
《吃水不忘挖井人》教学反思
2014/04/15 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
保研导师推荐信
2015/03/25 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
投资公司董事长岗位职责
2015/04/16 职场文书
幼儿园辞职信
2015/05/13 职场文书
2015重阳节座谈会主持词
2015/07/30 职场文书
公司车辆管理制度
2015/08/04 职场文书
意外事故赔偿协议书
2016/03/22 职场文书