The implementation of hexagonal hexagonal reactjs Janos pasztor

Jiedao jdon 2021-05-03 16:59:17
implementation hexagonal hexagonal reactjs janos


ReactJS Is the main force of front-end development , But it's in SOLID Can we change it by adopting the classic method ?

Will be ReactJS As UI Modern JavaScript When it comes to solutions , A lot of people seem to have problems organizing code . Let's have a deeper understanding of , See if we can do better .

A quick tempered man can Get code now

What is? React?

Since I 20 It started years ago Web Since development , stay JavaScript It's always been a painful experience to write front-end code in . Mainly due to browser incompatibility , And because there's no viable component framework . Sure enough ,ExtJS And the new Sencha Has been listed , But using it is more painful than using it .

then React There is , Trying to solve these problems ,React Used JS Next generation version of , You can   Convert to a browser that is currently available . stay React in , You can create reusable components , for example :

class MyBlogComponent {
    render() { 
        return <div className="blogentry">
          <div className="blogentry__title">{this.props.title}</div>
          ...
        </div>;
    }
}

Then you can use these components in other components :

class FeaturedBlogPost {
    render() {
        return <MyBlogComponent title="Featured article" />;
    }
}

Each of these components has two parts : Properties and states . attribute props Is the parameter data passed from the outside . In the example above ,“title” Is an attribute . On the other hand , State is the internal state of a component . A good example of internal state is when you need to load data from the server in the component and display it .

These components eventually create what's called virtual DOM. This is a tree , Like the real DOM equally , But it's faster , faster . in fact , So fast , It can recalculate the entire... For each state change DOM.

then ,React Will accept virtual DOM And compare different versions , In order to find out the real DOM What needs to be updated .

FLUX/REDUX framework

As you might imagine , The initial implementation was not completely flawless . Each component needs to maintain its own internal state , When two different components use the same data , There are often inconsistencies , Because the data will be loaded from the server at different times .

Try to solve this problem ,FLUX or REDUX Architecture was born . The two are slightly different , But for the purpose of this article , We see them as a .

The core idea is that the application has a central state , You can store everything in your application . When a component triggers an operation , This action will change the State ( By operating the creator function ), This, in turn, will use the global state to change the rendering of the component .

Of course , This provides a centralized architecture , State processing can be separated from a single component , Make it natural .

however , As you may have guessed , This architecture also has its balance problems . First , It has a focus   state , It's basically a giant god object that stores all the data in the application . My second problem focuses on the non-point of the solution SOLID On the issue of . To change part of the application , You have to touch... In the app ( And test the ) Various code parts , And changes in data structure can have a wide range of consequences .

hexagon Hexagonal framework

A very good architecture for me is hexagon / hexagon , Or I like to call it biscuits cutter framework . This kind of architecture makes use of different services to operate , And the entity entites Data transfer as a structured format .

For a long time , There's no way for me to Javascript Recreate the architecture in , Because it has no dependency injection or static type . However , lately , I've been using Typescript and Blueprint As React The component framework of , I managed to find a way to build a similar system .

First , We're going to start with business logic . for example , We will build a AuthenticationService. Contrary to my previous article describing the back-end architecture , The main location of storage state will be the service layer . therefore , The authentication service has several local fields :

class AuthenticationService {
    private accessToken: IAccessToken|null = null;
    private account: IAccount|null = null;
}

These entities can be defined as such a simple interface :

interface IAccessToken {
    readonly id: string;
    readonly accountId: string;
    readonly expires: LocalDateTime;
}

When converted to JavaScript when , These will be represented by regular objects . Because we're building services , So we need some more dependencies , These dependencies can be injected as expected through constructors :

class AuthenticationService {
    //...
    public constructor(
        readonly authenticationBackend: IAuthenticationBackendApi
    ) {
    }
}

Last , Let's add an authentication method :

class AuthenticationService {
    //...
    public authenticate = (username: string, password: string): Promise<boolean> => {
       
    };
}

As you can see , We are using promises, Because the authentication process takes time .promises After completion , The authentication process has completed or failed . Then we can implement such a login form :

class AuthenticationDialog
    extends React.Component<IAuthenticationDialogProps, IAuthenticationDialogState>
{
    render = () : JSX.Element => {
        return <form>
          <input ... />
          <input ... />
          <button onClick={this.onLogin} />
        </form>
    };
    private onLogin = () => {
        this.setState({
            loading: true
        });
        const self = this;
        this.props.authenticationService
            .authenticate(this.state.username,this.state.password)
            .catch(() => {
                self.setState({
                    loading: false
                });
                //Authentication process failure
            })
            .then((result: boolean) => {
                self.setState({
                    loading: false
                });
                if (result) {
                    //Successful login
                } else {
                    //Failed login
                }
            })
    };
}

Handling events

up to now , We only respond to events   So how do you update... Based on what's happening React Components ? Let's stick with the authentication example . Let's take a look at our authentication service :

class AuthenticationService {
    //...
    registerAuthenticationChangeListener(listener: IAuthenticationChangeListener):void {
    }
    deregisterAuthenticationChangeListener(listener: IAuthenticationChangeListener):void {
    }
}

So we added these two new functions , Allow components to register themselves as event listeners . In components , You can do the following :

class RequireAuthenticated
    extends React.Component
    implements IAuthenticationChangeListener
{
    public state : IAuthenticationContextState = {
        isAuthenticated: false
    };
    public componentDidMount = (): void => {
        this.props.authenticationService.registerAuthenticationChangeListener(this);
        this.onAuthenticationChange();
    };
    public onAuthenticationChange = ():void => {
        this.setState({
            isAuthenticated: this.props.authenticationService.isAuthenticated()
        });
    };
    public render = () => {
        return this.state.isAuthenticated?this.props.children:[];
    }
}

As you can see , This component displays the content only when the user is authenticated . When a component appears , It will register itself with the authentication service , In order to be informed when the state changes . This will allow DOM Trees change when their state changes .

Construct component tree

You may notice that the authentication dialog box takes the authentication service as prop. therefore , When you want to create this authentication dialog , You have to do this :

const authService = new AuthenticationService();
const authDialog = <AuthenticationDialog authenticationService={authService} />

obviously , This makes the process of creating a component tree a bit confusing . To solve this problem , We will use the factory :

class AuthenticationDialogFactory {
    public constructor(
        readonly authenticationServiceFactory: AuthenticationServiceFactory
    ) {
    }
    public create = () : JSX.Element => {
        return <AuthenticationDialog
            authenticationService={this.authenticationServiceFactory.create()}
        />
    }
}

And then it will be in our index.jsx File to build the root application .

Get the code

Now you have a good idea of what's going on , You can   from GitHub Get the code from .

Besides , You can do this by adding React.DI To extend this solution .

Conclusion

During my experiment , I find it very easy to write and debug such code . This is more bytes , But it can save a lot of trouble when debugging things . however , It's not the only feasible solution ​​ The solution .

版权声明
本文为[Jiedao jdon]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/05/20210503165711731c.html

  1. 浅谈 React 中的 XSS 攻击
  2. XSS attack in react
  3. 自学前端教程整理,附不容错过的前端100篇文章合集
  4. Self taught front-end tutorial collation, with a collection of 100 front-end articles that can not be missed
  5. 使用OpenTracing跟踪Go中的HTTP请求延迟
  6. Using opentracing to track HTTP request latency in go
  7. Encapsulating databinding allows you to write less than 10000 lines of code
  8. 03-HTML5标签-HTML5极速入门
  9. 03-html5 tag-html5 quick start
  10. LayUI - 极易上手拿来即用的前端 UI 框架
  11. Layui - easy to use front end UI framework
  12. Interpretation of lodash source code (1)
  13. Why is the first parameter of node family callback error?
  14. 报告:JavaScript 开发者达1380 万,C#超越 PHP,Rust 增长最快
  15. Report: Javascript developers reach 13.8 million, C surpasses PHP, and rust grows fastest
  16. 小白前端入门笔记(10),怎么设置网站内部的超链接?
  17. How to set up hyperlinks inside the website?
  18. Using node and socket to realize online chat room
  19. The core competitiveness of Vue: data bidirectional binding
  20. React configuration agent
  21. CSS layout
  22. Application scenario explanation of Vue dynamic component
  23. Redux learning notes 04 -- using multiple reducers to manage data
  24. After three months of typescript writing, what have I learned?
  25. Node family - what is a callback?
  26. React -- a simple implementation of render & create element
  27. JS learning simple usage of jquery
  28. Seamless love
  29. 小白前端入门笔记(12),设置哑链接
  30. Small white front-end entry notes (12), set dumb links
  31. Vue2. X opens composition API and TSX
  32. Interview record and thinking of social recruitment for one and a half years (Alibaba, Tencent, baidu offer)
  33. Flex learning notes
  34. The most essential closure article in the eastern hemisphere
  35. 2021-05-03 hot news
  36. Sword finger offer -- reverse order pair in array (JS Implementation)
  37. Working process of scaffold
  38. Use decorator mode to strengthen your fetch
  39. [JS] scope (Introduction)
  40. Employment information statistics network (interface document)
  41. Analysis of MVC
  42. [middle stage] please stay and join me in the backstage
  43. Understanding front end garbage collection
  44. [continuous update] front end special style implementation
  45. Flutter product analysis and package reduction scheme
  46. XPath positioning
  47. 前端开发css中的flex布局的使用
  48. The use of flex layout in front end development CSS
  49. JQuery核心函数和静态方法
  50. JQuery core functions and static methods
  51. Node family - understanding of blocking and non blocking
  52. 热点微前端Microfrontend的讨论:谷歌AdWords是真实的微前端
  53. Vue source code analysis (2) initproxy initialization proxy
  54. What's TM called react diff
  55. Summary of common front end data structure
  56. Useeffect in hooks
  57. [encapsulation 02 design pattern] Command pattern, share meta pattern, combination pattern, proxy pattern, strategy pattern
  58. Front end notes: virtual Dom and diff of vue2. X
  59. The best code scanning plug-in of flutter
  60. The simplest plug-in for rights management of flutter