React碰到v-if

77次阅读

共计 2880 个字符,预计需要花费 8 分钟才能阅读完成。

最近在重构公司老项目,由于本人以前的技术栈是 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”> 贝壳首页 </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 中模拟 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”> 贝壳首页 </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
好了,讲解完毕。

正文完
 0