zoukankan      html  css  js  c++  java
  • React碰到v-if

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

    废话不多说,直接上一段代码。

    import React from 'react'
    
    const App = () => {
      const record = {
        toKe: true, // 贝壳首页
        toSecondHand: true, // 二手房
        toFang: true, // 新房
      }
      return (
        <div style={{ 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
    

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

    {
        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-if

    先上代码

    import React from 'react'
    import Hidden from './Hidden'
    const App = () => {
      const record = {
        toKe: true, // 贝壳首页
        toSecondHand: true, // 二手房
        toFang: true, // 新房
      }
      return (
        <div style={{ 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去控制是否渲染。

    相信聪明的你一定知道怎么去封装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
    如下

    原来的横着排列的元素,一下子竖着排列了。这可不太好,本来给我套个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">贝壳首页</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

    好了,讲解完毕。

    原文地址:https://segmentfault.com/a/1190000016897137
  • 相关阅读:
    ZOJ 4097 Rescue the Princess
    最大值最小化 最小值最大化
    SD第九届省赛B题 Bullet
    Euler Circuit UVA
    bzoj 1878
    随笔
    BZOJ
    主席树模板
    AC自动机模板
    BZOJ
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9903454.html
Copyright © 2011-2022 走看看