浅谈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 相关文章推荐
Input 特殊事件onpopertychange和oninput
Jun 17 Javascript
jquery 最简单易用的表单验证插件
Feb 27 Javascript
jquery中show()、hide()和toggle()用法实例
Jan 15 Javascript
原生js和jquery实现图片轮播淡入淡出效果
Apr 23 Javascript
在AngularJS中使用jQuery的zTree插件的方法
Apr 21 Javascript
JavaScript实现页面跳转的方式汇总
May 16 Javascript
BootStrap实现树形目录组件代码详解
Jun 21 Javascript
node.js中实现kindEditor图片上传功能的方法教程
Apr 26 Javascript
Angular实现的简单查询天气预报功能示例
Dec 27 Javascript
jQuery实现常见的隐藏与展示列表效果示例
Jun 04 jQuery
Vue中的v-for指令不起效果的解决方法
Sep 27 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
Jul 27 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命名空间(Namespace)的使用详解
2013/05/04 PHP
Laravel 4 初级教程之安装及入门
2014/10/30 PHP
php管理nginx虚拟主机shell脚本实例
2014/11/19 PHP
Yii2.0中的COOKIE和SESSION用法
2016/08/12 PHP
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
nodejs 整合kindEditor实现图片上传
2015/02/03 NodeJs
Jquery使用css方法改变样式实例
2015/05/18 Javascript
基于Layer+jQuery的自定义弹框
2020/05/26 Javascript
遍历json获得数据的几种方法小结
2017/01/21 Javascript
基于JavaScript实现多级菜单效果
2017/07/25 Javascript
从零开始最小实现react服务器渲染详解
2018/01/26 Javascript
Vue触发式全局组件构建的方法
2018/11/28 Javascript
JavaScript数组、json对象、eval()函数用法实例分析
2019/02/21 Javascript
javascript实现简易的计算器
2020/01/17 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
2020/11/17 Javascript
[02:49]DAC2018决赛日TOP5 LGD开启黑暗之门绝杀VP
2018/04/08 DOTA
Python中__call__用法实例
2014/08/29 Python
在Python程序中实现分布式进程的教程
2015/04/28 Python
python中OrderedDict的使用方法详解
2017/05/05 Python
Python 处理数据的实例详解
2017/08/10 Python
20个常用Python运维库和模块
2018/02/12 Python
python将文本分每两行一组并保存到文件
2018/03/19 Python
django3.02模板中的超链接配置实例代码
2020/02/04 Python
python GUI库图形界面开发之PyQt5控件QTableWidget详细使用方法与属性
2020/02/25 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
使用数据结构给女朋友写个Html5走迷宫游戏
2019/11/26 HTML / CSS
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
Bose加拿大官方网站:美国知名音响品牌
2019/03/21 全球购物
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
Athleta官网:购买女士瑜伽服、技术运动服和休闲运动服
2020/11/12 全球购物
大学生简历中个人的自我评价
2013/10/06 职场文书
四风问题对照检查材料整改措施
2014/09/27 职场文书
2015年精神文明建设工作总结
2015/04/21 职场文书
2015年法律事务部工作总结
2015/07/27 职场文书
2016年党员学习廉政准则心得体会
2016/01/20 职场文书