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

好了,講解完畢。

相關文章
相關標籤/搜索