React碰到v-if

最近在重构公司老项目,因为本人之前的技术栈是vue, 换工做后发现如今公司的技术栈是react, 因此重构的过程是及其痛苦。加之项目又是几年前的老项目,不敢大改,比葫芦画瓢比比皆是。本文就介绍下遇到的一个经常使用的痛点。欢迎大佬指正。html

废话很少说,直接上一段代码。vue

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">贝壳首页</a>
            : null
          }
          {
            record.toSecondHand
            ? <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/">二手房</a>
            : null
          }
          {
            record.toFang
            ? <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/">新房</a>
            : null
          }
        </li>
      </ul>
    </div>
  )
}
export default App

如上述代码,咱们在项目中会遇到不少这样的写法, 细看一下没什么问题,但是当在重构老项目的时候,你会发现这个代码结构是多么痛苦,特别是以下的结构。react

{
    record.toFang && record.toKe && record.toSecondHand
    && <div>
       <a style={{padding: 20}} href="https://bj.ke.com">贝壳首页</a>
       <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/">二手房</a>
       <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/">新房</a>
   </div>
}

虽然代码逻辑没问题,但人生就是这样,有时候出场顺序真的很重要。忽然就想起vue的v-if了。
没错,回归主题,就是:react中模拟vuev-ifvue-router

先上代码api

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">贝壳首页</a>
          </Hidden>
          <Hidden visible={record.toSecondHand} tag='span' style={{padding: 20}}>
            <a href="https://bj.ke.com/ershoufang/">二手房</a>
          </Hidden>
          <Hidden visible={record.toFang} tag='p'>
            <a href="https://bj.fang.ke.com/loupan/">新房</a>
          </Hidden>
        </li>
      </ul>
    </div>
  )
}
export default App

简单就是封装Hidden组件,经过visible去控制是否渲染。ide

相信聪明的你必定知道怎么去封装Hidden布局

笔者刚开始是这么写的ui

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
以下
图片描述this

原来的横着排列的元素,一会儿竖着排列了。这可不太好,原本给我套个div,我均可以勉强接收,如今连我布局都给我变了。
怎么办?笔者忽然想到使用vue-router中的router-link时,标签是能够经过tag去替换默认标签的。
那咱们再给它个tag呗,连带自定义属性。spa

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">贝壳首页</a>
       <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/">二手房</a>
       <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/">新房</a>
    </span>
}
<Hidden 
   visible={record.toFang && record.toKe && record.toSecondHand} 
   tag='span'>
   <a href="https://bj.ke.com">贝壳首页</a>
   <a style={{padding: 20}} href="https://bj.ke.com/ershoufang/">二手房</a>
   <a style={{padding: 20}} href="https://bj.fang.ke.com/loupan/">新房</a>
</Hidden>

其实感受也没多大用处hhhh

好了,讲解完毕。

相关文章
相关标签/搜索