浅谈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中创建对象的几种方式示例介绍
Jan 26 Javascript
JS实现从连接中获取youtube的key实例
Jul 02 Javascript
浅谈Javascript线程及定时机制
Jul 02 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
Dec 26 Javascript
vue和react等项目中更简单的实现展开收起更多等效果示例
Feb 22 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
Mar 20 Javascript
详解webpack模块化管理和打包工具
Apr 21 Javascript
Layui动态生成select下拉选择框不显示的解决方法
Sep 24 Javascript
jQuery弹框插件使用方法详解
May 26 jQuery
Vue.js暴露方法给WebView的使用操作
Sep 07 Javascript
vue实现动态表格提交参数动态生成控件的操作
Nov 09 Javascript
详解Vue的列表渲染
Nov 20 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
第1次亲密接触PHP5(2)
2006/10/09 PHP
一个程序下载的管理程序(三)
2006/10/09 PHP
isset和empty的区别
2007/01/15 PHP
PHP 函数语法介绍一
2009/06/14 PHP
利用php递归实现无限分类 格式化数组的详解
2013/06/08 PHP
laravel-admin 在列表页添加自定义按钮的例子
2019/09/30 PHP
js调用flash的效果代码
2008/04/26 Javascript
Javascript 同时提交多个Web表单的方法
2009/02/19 Javascript
JavaScript的事件绑定(方便不支持js的时候)
2013/10/01 Javascript
javascript对中文按照拼音排序代码
2014/08/20 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
2015/11/15 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
layui radio点击事件实现input显示和隐藏的例子
2019/09/02 Javascript
layui的面包屑或者表单不显示的解决方法
2019/09/05 Javascript
微信小程序返回箭头跳转到指定页面实例解析
2019/10/08 Javascript
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
2019/11/18 NodeJs
vue 动态表单开发方法案例详解
2019/12/02 Javascript
详解js中的几种常用设计模式
2020/07/16 Javascript
jQuery带控制按钮轮播图插件
2020/07/31 jQuery
ajax jquery实现页面某一个div的刷新效果
2021/03/04 jQuery
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
python以环状形式组合排列图片并输出的方法
2015/03/17 Python
python 与GO中操作slice,list的方式实例代码
2017/03/20 Python
python dlib人脸识别代码实例
2019/04/04 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
python函数参数(必须参数、可变参数、关键字参数)
2019/08/16 Python
使用Python进行中文繁简转换的实现代码
2019/10/18 Python
python获取array中指定元素的示例
2019/11/26 Python
python中的逆序遍历实例
2019/12/25 Python
斯福泰克软件测试面试题
2015/02/16 面试题
喷漆工的岗位职责
2014/03/17 职场文书
公文写作:教你写“建议书”
2019/05/07 职场文书
Html5大屏数据可视化开发的实现
2021/06/11 HTML / CSS
Vue.Draggable实现交换位置
2022/04/07 Vue.js