你可能并不真正了解JSX真正的用意,怎么用JSX进行解耦...

1,774 阅读5分钟

在不久之前,我发了一条沸点。内容大致以下吧,首先用什么并没有对错,取决于你是更偏好那方面。

image.png

然后我的意思,其实很简单。为什么我说你喜欢用JS的话,你用React呢?这也是本文想说的。因为发现大多人github上的开源React项目并没有用到React推荐Jsx的初衷。

image.png

但是我发现确得到很多人的喷,其中有那么一个人的回复让我感觉我看的是假的Anular2源码。以下是一些废话,也可以跳过,喷我的那个人是一位算法工程师吧。估计也是够牛的人。

image.png

image.png

image.png

我是一个热爱用javascript编程的人,我会选择React多一点,毕竟React的全家桶千奇百怪的轮子(Redux,Mobx,Dva,当然你要是架构思维强的话,可以直接用Rxjs的观察者模式来搞,但是前提你得精通单列模式应用和js的作用域),换成vue选择性就少了很多几乎都是vue全家桶,但是如果你想使用设计模式去管理你的应用开发,那么还是建议使用Ng2,在开发过程中,你会学到ioc,依赖注入,单列,修饰器(aop),观察者(响应式流)。 如果说DDD模式开发以后是趋势的话,那NG2的服务/Http基于Rxjs提供给你的方式,真的太合适了。

说的有点偏离了。回到主题。

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们不需要一定使用 JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

注意重点,React使用 JSX 来替代常规的 JavaScript。那就是说Jsx的本质还是JavaScript代码。

你可以在Jsx里面做渲染func操作。

下面我们来个简单的场景,就是做商品推荐功能,需要给不同客户在某一个栏目,推不一样的内容。那么你们会怎么做呢?在我平时corde review的工作中发现大部分的开发者做法占用率70%是以下的写法,但以中国的市场来说,怎么快怎么来。反正维护的时候也就跑路了。而且领导也很少去管代码的事,能跑就行。

/**

* 这里有三个人

*/

enum PersionType {

Man = 1,

Woman = 2,

OldMan = 3

}

function HomePage() {

    const fetchGetQuery = ()=>{
        return 1
    }


    const data = fetchGetQuery()

    return <Observer>{() => {

        return (

        <>

            {

            data === PersionType.Man && (<>Man View</>)

            }

            {

            data === PersionType.Woman && (<>Woman View</>)

            }

            {

            data === PersionType.OldMan && (<>OldMan View</>)
            }
        </>)
    }}</Observer>;

}

export default HomePage;

设想一下,如果你以后的业务不在是三个人的时候,你会怎么处理?都已经是屎山代码了,那就继续往屎山上堆积吧!!!

那就继续在这个页面加

 {
    data === PersionType.XXXXX && (<>XXXX View</>)
 }

但是试想一下,因为JSX的底层还是Javascript那你会怎么去写以上的代码呢?哦哦不对React的开发者多数是Typescript。换做是ng和vue这一类的mvc方面的思路,我还真的不知道怎么解决,因为以传统的后代做法也就改一下include的模版路径。毕竟html不是执行代码。

如果你学过设计模式,那么以上的例子,无疑可以使用策略模式进行结偶。让你可以在改少量代码的同时让你的代码看起来更在清爽。

我们先对文件夹进行简单的结构分层

1. index.tsx    //我们上下PersionContext也可以是我们的调用者
2. view-strategy.tsx   //定义规范的接口
3. main.tsx            //实现的地方

image.png

handle/index.tsx

import { ViewStrategy } from "./view-strategy";

class PersonContext {

    private viewStrategy: ViewStrategy;

    constructor(viewType: ViewStrategy) {
        this.viewStrategy = viewType;
    }

    public renderView() {
        return this.viewStrategy.render();
    }

}

export default PersonContext;
handel/view-strategy.tsx

import React from "react";


export interface ViewStrategy {

render():React.ReactElement;

}
handle/man.tsx

import React from 'react';

import { ViewStrategy } from './view-strategy';


class Man implements ViewStrategy {

    render(): React.ReactElement<any, string | React.JSXElementConstructor<any>> {

        return (

            <>Main View</>

        );

    }

}

export default Man;

以上是我们实现的三个最基本的关系,那么我们现在要对我们的页面进行什么操作呢?

我们这需要

function HomePage() {

const fetchGetQuery = ()=>{
    /**

    * 你自己做的业务逻辑进行判断,然后以后只需要进行维护这一刻的代码,数据建议操作sotre里面,这样你就可以去sotre拿数据,无需要

    * 传参数了,当然最好的方式使用rxjs进行监听,这么你的PersionType改变,你的view也同时变化。你只需要监听ViewStrategy的类型

    */
    if(true){
        return new Woman()
    }

}


const data = fetchGetQuery()

return <Observer>{() => {

    return (

        <>

            {new PersonContext(data).renderView()}

        </>

    )

}}</Observer>;

}

上面的代码,你就可以完全脱离了。以后要维护那个木块不一样的方式的时候,你只需要把你写好的逻辑,在fetchGetQuery()进行维护即可。

有人会好奇,这么写能运行吗?

image.png

那你说能运行吗?

React本来在Jsx是不提供If/else的写法。但是我确发现很多开发者是喜欢这么写的。

{
    data === xxx && ()
}

{
    data !=== xxx && ()
}

# 如果有循环的时候,这不是问题。但是你确定你不会遇到有递归的时候吗???
{
    data.map(val=> <> XXXX </>)
}

其实以上的写法都可以用函数进行渲染,因为JSX的底层是Javascript啊...我并不知道为什么大多数开发者都喜欢在HTML上面做文章,如果这么做的话,你还不如用模板引擎。那什么是模板引擎?你问问后端不久懂了。模板引擎的实际是操作语言去操作字符串,使用替换的方式进行替换。但是JSX不一样,它的出生就和babel死死绑定在一起。 通过babel转javascript...。

所以你jsx的操作,实际是在写javscript代码。而不是ng,vue这一类的类mvc框架。

所以说,你遇到复杂的逻辑的时候,完全可以使用类似一下的做法。类似我这里做的Route递归

image.png

就完全可以这么写if else了,你甚至可以写switch或者做更多的骚操作。 image.png

好了今天的分享到这里。期待你的更多骚操作。希望通过这次,前端能有新的感受吧,毕竟前端是面向下一个阶段DDD,连设计模式都还用不上,我真的不知道什么时候前端的人群可以普及使用rxjs来处理复杂的异步问题。