淺談React碰到v-if
最近在重構(gòu)公司老項目,由于本人以前的技術(shù)棧是vue, 換工作后發(fā)現(xiàn)現(xiàn)在公司的技術(shù)棧是react, 所以重構(gòu)的過程是及其痛苦。加之項目又是幾年前的老項目,不敢大改,比葫蘆畫瓢比比皆是。本文就介紹下遇到的一個常用的痛點。歡迎大佬指正。
廢話不多說,直接上一段代碼。
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常規(guī)寫法</h3>
{
record.toKe
? <a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >貝殼首頁</a>
: null
}
{
record.toSecondHand
? <a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
: null
}
{
record.toFang
? <a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
: null
}
</li>
</ul>
</div>
)
}
export default App
如上述代碼,我們在項目中會遇到很多這樣的寫法, 細(xì)看一下沒什么問題,可是當(dāng)在重構(gòu)老項目的時候,你會發(fā)現(xiàn)這個代碼結(jié)構(gòu)是多么痛苦,特別是如下的結(jié)構(gòu)。
{
record.toFang && record.toKe && record.toSecondHand
&& <div>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >貝殼首頁</a>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
<a style={{padding: 20}} 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模擬實現(xiàn)vue中v-if指令</h3>
<Hidden visible={record.toKe} tag='span'>
<a 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 rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
</Hidden>
<Hidden visible={record.toFang} tag='p'>
<a 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>
)
}
}
如此簡單,但筆者審查元素的時候發(fā)現(xiàn),每個Hidden下的children莫名被嵌套了一層div
如下

原來的橫著排列的元素,一下子豎著排列了。這可不太好,本來給我套個div,我都可以勉強(qiáng)接收,現(xiàn)在連我布局都給我變了。
怎么辦?筆者突然想到使用vue-router中的router-link時,標(biāo)簽是可以通過tag去替換默認(rèn)標(biāo)簽的。
那我們再給它個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 (
// 嘗試用這種方法去實現(xiàn),發(fā)現(xiàn)不符合react的規(guī)則,所以使用最原始的渲染方法
// React.createElement
// `<`${tag}`>` + { content } + `</`${tag}`>`
// )
}
}
問題:筆者的初衷是模擬vue的v-if, 所以對傳入的children并沒做太多處理,不建議做多做封裝。有興趣的同學(xué)可以自己玩。
{
record.toFang && record.toKe && record.toSecondHand
&& <span>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >貝殼首頁</a>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
<a style={{padding: 20}} 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 rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >貝殼首頁</a>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >二手房</a>
<a style={{padding: 20}} rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >新房</a>
</Hidden>
其實感覺也沒多大用處hhhh
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React?Native實現(xiàn)Toast輕提示和loading效果
這篇文章主要介紹了React Native實現(xiàn)Toast輕提示和loading效果,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
React-router?v6在Class組件和非組件代碼中的正確使用
這篇文章主要介紹了React-router?v6在Class組件和非組件代碼中的正確使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
React應(yīng)用框架Dva數(shù)據(jù)流向原理總結(jié)分析
這篇文章主要為大家介紹了React 應(yīng)用框架Dva數(shù)據(jù)流向原理總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
關(guān)于React Native使用axios進(jìn)行網(wǎng)絡(luò)請求的方法
axios是一個基于Promise的Http網(wǎng)絡(luò)庫,可運(yùn)行在瀏覽器端和Node.js中,Vue應(yīng)用的網(wǎng)絡(luò)請求基本都是使用它完成的。這篇文章主要介紹了React Native使用axios進(jìn)行網(wǎng)絡(luò)請求,需要的朋友可以參考下2021-08-08

