preface

Note: This article does not contain all content related to hooks

Because hooks are used in react project, but there are no hooks in vue2.x project, among the existing development modes, we mostly use the componentized development mode, but in the increasingly complex business logic, it seems that the componentized development cannot fully meet our needs. The deeper the advantages of component-based development, the greater the maintenance risks and costs. React officials found the problems as early as possible, so, hooks were born

Of course, hooks don’t just solve the problem of componentized development, but I think they’re one of the main reasons

For reasons related to the creation of hooks, please redirect to the official address

Is the hooks solution the best solution

I don’t think so. Those of you who have read my little book can see the point I’ve been describing:

The best framework is always in the future. The birth of any framework is based on needs. Be in awe of everything that exists, but also be skepticalCopy the code

With such a mindset, I have made a probe and investigation for nearly half a month in various forums, blogs, wechat groups and other channels based on my existing business scenario, and found that it cannot meet our needs. The first hard hit is that it is directly passed the program, which is the root cause: the disunity of the framework

The existence of hooks is probably more in line with one of my previous ideas: clean, which allows us to separate all behaviors, layouts, and presentations to make components purer, but not perfectly covering complex business scenarios

The following is a preliminary result of my own research and discussion with netizens, which belongs to the embryonic stage, and I hope we can discuss moreCopy the code

Project Scenario Case

In the process of many years of development experience, the existing known development patterns can not meet all my needs. Componentization development and code reusability can meet most of my working patterns, but they can not provide me with the expected results I want to achieve when I encounter many tedious and complex requirements:

The same function (page), based on the part of the function is consistent, such as a bullet box, there are two public popup window, name and age, for the operation of the user information for different pages, we have different data processing, but there is a user’s data in the table, so we request the interface is also a, At this point we’ll wrap it up and write it as a component:

All of the code snippets below are pseudocode, just to show you a general example, do not run demo as actual code

function Dialog(props) {
  function submit() {
    fetch({
      url: 'save'.method: 'post'.data: {
        // All parameters}})}const { children } = props
  return (
    <div>
      <div>
        <label>The name</label>
        <input />
      </div>
      <div>
        <label>age</label>
        <input />
      </div>
      {children}
      <div>
        <button onclick="submit">confirm</button>
      </div>
    </div>)}Copy the code

This way we can use it in different pages, and we can use chilren to put in the corresponding categories of conditions, but there is no need to strip out the requested interface anyway

At this time, we may have three pages to use this component, one page needs to add an age text box, one page needs to add an age, occupation text box, and one page needs to add a native place text box, we found that part of the function is repeated and can be reused is the age text box, We tried to strip it out and call it as a separate component

Of course, in the actual project, there is not only a text box, maybe different drop-down boxes will have different logical judgment, but the functional destination is the same, do not strip write n, not easy to maintain, strip write one, nesting hell is thus generated

The birth of an idea

Based on the above conditions, I am considering how to solve the problem perfectly. Only by discovering the essence of the problem can we better solve the problem. In this case, I think the root cause of the problem is that the process, the pages used or the interfaces output are unified

In combination with my knowledge over the years and the business scenario, I came up with a solution. Can we solve this problem through the middleware pattern?

Entry -> Middleware (step 1 processing, step 2 processing….) – > export

The problem is identified, the solution is figured out, and the next step is to solve the problem

Components – step mode

This is not a framework, nor is it a tool, but a new way of thinking based on componentized development to improve development efficiency, code readability, and code maintainability, which I call component step:

Git address: github.com/nextdoorUnc…

Welcome to fork, Star, issues

The installation

npm

npm install --save components-step
Copy the code

yarn

yarn add components-step
Copy the code

use

import ComponentsStep from 'components-step'

ComponentsStep([mid1,mid2])(container, attr)
Copy the code

This model I call it a component step Is I think it is to do things step by step, the next step of the action will always be based on the previous step, can guarantee the stability of the input and output, called in front of the middleware through middleware is the cause of this concept to understand the component steps may be faster and more convenient for some, after all, this is a kind of development mode, It’s not a feature

Based on the requirements I described above, let’s do the following steps through the component:

Components – step function

Solve redundant code

The first thing we need to make sure is that our code does not duplicate. Solving duplicate code is the first step:

function Mid1(props) {
  console.log(props, this)
  return () = > {
    console.log(this)
    return (
      <div>mid1 {props ? 'true' : 'false'}</div>)}}function Mid2(props) {
  return () = > {
    return (
      <div>mid2 {! props ? 'true' : 'false'}</div>)}}Copy the code

Let’s assume that the above method is our logic that repeats under different conditions and we’ll strip it out. The way we write it here is a little different from the way we usually write it. It’s an extra layer of return, which I haven’t figured out yet, but I left it out for the possibility that we will do middleware processing in the future

So the different ones can be stripped out, so we don’t have to write the same code twice, so that’s the first step

Flexibility of component rendering based on different conditions

While there are similarities to the concept of middleware, middleware plays a supporting role in the development process, each step of component step is important and will directly determine the contents of our future containers. What content needs to be presented to the user:

import ComponentsStep from 'components-step'

const step = ComponentsStep([
  {
    label: 'Step1'.stepItemMiddle: Mid1
  },
  {
    label: 'Step2'.stepItemMiddle: Mid2
  }
])
Copy the code

ComponentsStep: ComponentsStep: ComponentsStep: ComponentsStep: ComponentsStep: ComponentsStep

  • label: Each identifier, when rendered in the parent container, is the container for that step
  • stepItemMiddle: the method used to render the required component. The return value must be onefunction component

A function that returns ComponentsStep is a function that receives two values, one for a container and one for an attr. Because the rendering of a component may depend on certain conditions to complete, the container is where we need to place the step component. Since the position of the component rendering is not controllable, we can not return a single queue, which is not convenient for our step component rendering

Flexibility of container rendering

Based on the requirements of componentization development above, we may have the same function to render in different pages, so we need to open different pages, that is, our container entry, to ensure the simplicity and flexibility of the function:

function HighFn(atom, attr) {
  return class extends Component {
    constructor() {
      super()}render() {
      return (
        <Dialog {. atom} / >)}}}const arg = 1
step(HighFn, arg)
Copy the code

The flexibility of the container directly affects the utility of our function, and the frequent function calls also affect the speed of rendering. In order to maintain these two conditions, I put them in the return function parameters of ComponentsStep

HighFn is a container and arG is a parameter. After step is called, highFn’s function will receive two parameters: The Step component set (Atom) and the parameter (ATTR).

Data to support

At present, component-step can very well meet my business needs, and the overall data comparison is considerable:

The following index is based on my current business code to do the data statistics, the error interval and statistics are not largeCopy the code
indicators Before using After using
Amount of code 500 lines 300 lines
Code reading time 60s 30s
Maintenance costs All correlation functions need to be tested The independence is stronger and the correlation strength is lower

conclusion

That’s about all I have to say about my ideas and my output for now, but I hope we can all share our opinions and work together to make the front end a better place

There may be a lot of bosses who will come up with better plans. I also hope to have the opportunity to learn. Knowledge will become more valuable in the process of discussion

Fork, star, issues: github.com/nextdoorUnc…

AD time

Some time ago, I wrote a small book: “Micro front end – from concept to development”, I also hope that we can support, you drink a cup of luckin, I will buy a day early Mercedes Benz, write not good spray, hold, next time to meet directly beat, OK?

~ ~ just kidding, or hope to have more good suggestions so that I can better output valuable and meaningful content to the community, thank you