review

jQuery

I remember that when I started to touch the front end in 2013, I was most excited when I hand-wrote a floating advertisement with native JS. At that time, jQuery was very popular. Now looking back, this may be the starting point of indirect UI operation through JS, and the core part of jQuery is also packaging Dom objects. Using regular matching to deal with CSS HTML, the web is full of jQuery effect codes that can be copied at will, and various jQuery plugins. At that time, the front end does not need too much professional computer knowledge, theoretically copy and paste can also complete most of the “weird” requirements, if you want to analogy, In fact, jQuery is quite ahead of its time. For example, the stranded webComponent is similar to jQuery Plugin, which is a Widget wrapped in JS, CSS and HTML that is shared through the Internet. Of course, the internal principles are quite different.

JQuery is not really a UI framework, but it opens up indirect manipulation of the Dom, an idea that is the foundation of modern UI frameworks and has had a profound impact

Handlebar

As requirements became more complex, more and more needed to render web pages in response to back-end data, and Dom manipulation in response to back-end data using jQuery became less efficient and difficult to maintain, Handlebar emerged, a template framework that many young front-end developers might not have heard of. But it was a big deal back in ’14. Handlebar allows you to write the Dom templates that need to be updated in advance, making it much more efficient to manipulate the Dom

Presents 1.0

Angular is the first UI framework in a sense. In contrast to developing SPA, you need to use Dom manipulation library, business logic framework such as Backbone, and a useful template processing framework such as Handlebar. It’s the UI framework/module dependencies/packaging project all in one, so you can expect it to be a big hit. But looking back at angular 1.0 from 2020, the whole idea was too big. In addition, the dirty check mechanism that the author himself felt was insane caused lack of API updates in the later period. With the rise of React, it gradually faded out.

React

In 2015, React suddenly became popular. The core of it was Virtualdom. Thanks to Virtualdom’s excellent rendering performance, React began to stand out, and its functional programming philosophy was very attractive. At that time, a lot of front-end enthusiasts were committed to introducing functional programming into the world of JavaScript. Coupled with the strong plasticity of JavaScript itself and the foundation of first-class function citizens, functional programming, which has always been a bit of a door in the field of business development, came into the public eye. Then Redux appeared. That wonderful lecture on time travel popularized the notion of immutable, Thuck, and other functions, so much so that at the time, no matter how complicated Redux was to write, I tried to keep all my logic on top of it, as if otherwise the code would be unmaintainable

In fact, until Hooks came along, React’s functional programming philosophy was a bit of a nonentity. Complex applications built on class Components, tied to Redux, a functional state-management library, awkward to look at, HOC, long call chains, It’s a bit of a test of patience to write, which is why redux-based platforms such as Dva reduce the cost of writing code, but in essence Redux goes from functional to object-oriented in one big package, introducing concepts such as Modules to correct the awkwardness

React grew out of functions, including HOC, to make the class component a little more functional, until the dev team designed Hooks, which remove conditional judgments from the imperative, lock scope each time using closures internally, React was completely functioned by means of quantization and so on. Faced with the new React, the concept of everything being functional was unprecedented, but at the same time, the “awkward” reached its peak. A large number of people in the community ridiculed that they could not write code properly. Both useMemo and useCallback are confusing for developers who are used to object-oriented style and imperative code. If we used to use immutable to avoid object mutability, most of the time we use this to share data via object references. If you want to get around the constants of Hooks, you have to maintain a reference to a mutable object using refs, everything seems reversed, we need to relearn how to write code, the mental cost of Hooks is almost subversive, However, TO be honest, I like functional design very much and appreciate the clever design. However, the React design method is probably awkward for people who like object-oriented style.

Vue

I once wrote about Vue, and it was always said on the Internet that Vue copied React, and Then Yuxi was busy putting out the fire. I think there are many people who hold this view. But to be fair, the open source technology itself is developed from each other. I think Vue and React are two completely different design philosophies. Even though they borrow from each other, the design philosophy behind React is completely different. Unlike React’s functional programming philosophy, I think Vue follows the design of Angular 1.0. This includes responsive data-driven manipulation of the UI by manipulating data. Template directives are imperative rather than functional. React never had an IF component built in, which is why Vue is so popular. As well as the object-oriented style is more easily accepted by the general development, after all, we are born to learn C, were trained in the university education of object-oriented programming, foundation, there really are more likely to accept this style of programming, actually for this two kinds of style of programming, I think just is a tai chi, his long, which is short of me

For example, if we were to develop a profile of a user, we might write something like this, thinking in terms of a face object

class UserProfile extends Widget {
    async constructor() {const profile = await axios.get('user/profile')
        this.email = profile.email
        this.name = profile.name
        this.phone = profile.phone
        // other propotype
    }
    get name(){
        return 'username:' + this.name
    }
    get email(){
        return emailHandler(this.email)
    }
    set name(localNameString){
        this.name = nameValid(localNameString)
    }
    @axios('pose'.'user/profile/upload')
    upload(){
        return {
            name:this.name,
            email:this.email,
            phone:this.phone
        }
    }
    render(){
        return {
            `
      
{{name}}
{{phone}}
`
}}}Copy the code

The object is the smallest unit, through inheritance and mixing with the object as the core to build applications, because in the design of the smallest unit of code is class, so there will be no logic belonging to the class and the logic belonging to the function mixed situation. In a language as flexible as JavaScript, it’s easy to write business logic out of class instead of encapsulating everything in a class like the example above, which was the case with React before Hooks came along, Class-based Components are mixed with a bunch of utility functions or function-level code, the minimum unit is inconsistent, and the logic reusability caused by mixed-style programming is difficult to guarantee. HOC is a compromise, but like render props, as the business code expands, Functionalreact badly needed a functional solution to make logic functional and get rid of object orientation once and for all. That is where Hooks came in. In a sense, Hooks are heroes.

With Hooks, we should try to forget about object orientation, for you, functions are the smallest unit, no properties, no methods, everything is the result of a chain operation, no variables and no conditions run, loops only use recursion, no for loops, under these constraints, That example is in the form of Hooks and functions

function upload(profile){
    axios.post('user/profile', profile)
}
function useSetProfile(profile){
    const [profile, setProfile] = useState([{
        name:profile.name,
        email:profile.email,
        phone:profile.phone
    }])
    return setProfile
}
asnyc function useSyncUserProfile(callback,deps){
    useEffect(async() = > {const profile = await axios.get('user/profile/upload')
        callback(profile)
    },deps)
}
function userProfileWidget(profile){
    const setProfile = useSetProfile({
        name:'jaka'.email:'[email protected]'.phone:'1123123'
    })
    useSyncUserProfile(setProfile,[profile])
    function onBtnClick(){
        setProFile(profile)
        upload()
    }
    return render(
        `
      
{{name}}
{{phone}}
`
)}Copy the code

Compared to the first class example, in the second example, our thinking unit is focused on the “function”. There is no completeness of the object, only input/output parameters for a function. The advantages of this are obviously finer granularity and easier to test, but the disadvantages are also obvious. For a function component to be self-explanatory, corresponding specifications need to be formulated in function naming. Unlike the natural cooperative concept of object-oriented classes/attributes/methods, the concept of function is too monotonous to describe the real world.

Let’s take a look at one of the programming styles that Vue3.0 gives us. In fact, Vue3.0 toned down the functional and object-oriented styles, and also added reactive styles to automatically trigger getters/setters, a little bit of streaming programming flavor

<template>
  <div class="name">{{name}}</div>
  <div class="email">{{email}}</div>
  <div class="phone">{{phone}}</div>
  <button @click="onBtnClick">
  </button>
</template>
<script>
  import { reactive, computed } from 'vue'
  function uplaod(profile){
      axios.post('user/profile/upload', profile)
  }
  function useSyncUserProfile(state){
      watchEffect(async ()=>{
        const profile = await axios.get('user/profile')
        state.name = profile.name
        state.email = profile.email
        phone = profile.phone
      })
  }
  export default {
    setup() {
      const state = reactive({
        name: 'jaka',
        email:'[email protected]',
        phone: 1833333,
      })
      onMounted(){
        useSyncUserProfile(state)
      }
      function onBtnClick() {
        upload(state)
      }

      return {
        state,
        onBtnClick,
      }
    },
  }
</script>
Copy the code

Vue introduced functional API and did not add strong constraints like React. It still has a life cycle. From a large structure, it looks like a combination of functions, which can be regarded as object functions.

So Vue is not as thoroughly designed as React, combining object-oriented descriptiveness with functional fine-grained composition. JavaScript itself is not reactive, so Vue has its own problems. In 2.0, it cannot automatically hijack arrays internally. There is no automatic hijacking of new object attributes. Proxy 3.0 solves this problem, but it also introduces a new problem: once reactive objects are deconstructed, everything is over. From this perspective, the core of Vue is still object-oriented, completely different from React. His Hooks are also based on JavaScript functions that are objects, rather than function closures like React.

However, whether React or Vue, I think the introduction of functional apis has actually increased the threshold for the framework to be able to write…. properly You have to learn a lot of new low-level details and follow conventions, as opposed to the old days where you just leave everything to the framework and the framework takes care of the code level constraints

These are still hot concepts, but they’re all in the past, so I’m starting to fantasize about what UI frameworks will look like in the next few years.

fantasy

React to stick with functions to the end

React Concurrent is currently in the lab, and the payoff for sticking to functional is that everything is functional, which is great for controlling rendering granularity down to the stack level, because JavaScript stacks are function stacks, Take advantage of the browser’s magic apis like RequesTidlecallBack to make 60fps rendering easier by squeezing executable functions in between CPU time slices. It’s not a fantasy, it’s a vision, it’s on the way. If we think a little further back, we all know that the concept of function as a service is often mentioned in the recent hot ServerLess. Microservices are replaced by functions, so the back-end is function as a service. If the front-end implements function as a render… This feels like a great unification of functions, so will future applications automatically run in series with a bunch of functions? Compared with the less reliable packaging of webComponent, 🤔 can realize the vision of webComponent by introducing Deno’s idea of module networking and distributing function components on the network, because of the consistency of granularity and the nature of functions easily understood by machines. Maybe we can write code like this in the future

import dataPicker from 'https://function/ui/component/data-picker'
import useWeiBoUserData from 'https://function/hooks/use-webbo-user-data'

async function app(){
    const weiboUserData = await useWeiBoUserData()
    render(){
        return {
            ` `` 
       
      
{weiboUserData.toJSON()}
`
` `}}}// HTML <div app="react"></div> Copy the code

No heavy packaging and compilation, browser built-in UI framework, and then share function components, function logic, function services over the network… It feels like a new era

If you still have what imagination can open, might as well stay in the comments, perhaps a number of cattle back can also blow a water, yesterday I predicted….