Single page application development summary

Time:2021-10-6

This paper wants to summarize the development of spa through my one page application development experience in this year.

Page development mode

Usually when we develop a page, we will get a design drawing. Suppose we get such a design drawing

Single page application development summary
For page development, I always follow the top-down design mode. Here, we will first divide the page into two parts, header navigation and content body. The content body is divided into two parts: the attention information on the left and the dynamic list on the right. If divided in this way, our component writing will look like the following

<Container>
  <Nav />
  <Body>
    <BodyLeft />
    <BodyRight />
  </Body>
</Container>

In fact, there is no problem in writing like this. Hide all the details inside the components. Each component just needs to deal with itself. However, you should know that today’s pages are more complex, and general single page applications need a reliable data flow to process, otherwise it will be very difficult to maintain in the future. Here, let’s assume that we use redux. In Redux, our data is transmitted from the top to the bottom. Generally, we use the route page as the dimension to connect, and then the route page distributes the required stores and actions in the form of props. That is equivalent to that only the route component of the whole page is an intelligent component, and other components are written as puppet components as much as possible. If you follow this development model to develop the left concern list component, it should be like this

//BodyLeft
<Container>
  <TopNav />
  <List />
</Container>

The list component should be like this

//List
<Container>
  {data.map(item=>(
    <Item>{item.name}</Item>
  ))}
</Container>

At this time, if the route page wants to transfer any information to the list on the left, it must be transferred layer by layer every time. If there is one less layer, there may be two or three more layers. This will write a lot of useless information and is not conducive to future maintenance, because every time there is a change, many useless places (those middle layers) have to be changed.
Personally, I prefer a flat component design style.
Or the original page. If the flat design mode is adopted, the designed component structure is like this

//PS: optional component name
<Container>
  <Nav>
    <NavLeft />
    <NavRight />
  </Nav>
  <Body>
    <BodyLeft>
      <LeftTop />
      <LeftList />
    </BodyLeft>
    <BodyRight>
      <ArticleList />
    </BodyRight>
  </Body>
</Container>

First, the outermost layout can be reused. This means that if there are pages like this, they can be used when the layout is up and down, and the layout is left and right below. Secondly, the data transfer does not need to be transferred layer by layer as before, but can be directly transferred to the desired components.

Some people say why the route page can’t be written like this

<div>
  <Nav />
  <div>
    <div className="left">
      <div className="leftTop">
        ...
      </div>
      <List />
    </div>
    <div className="right">
      <ArticleList />
    </div>
  </div>
</div>

In other words, it’s not good to replace the previous components with Div. However, in component design philosophy, usually in the connect component, that is, intelligent component, it does not deal with things related to view, and intelligent component only deals with data and logic. Everything related to the view is handled in the puppet component. The advantage is that as long as it is logical processing, it will find intelligent components, while interface styles will find puppet components, with clear ideas, lower coupling and high cohesion.

assembly

Many people’s understanding of components is reuse. In fact, another advantage of component development is modularity. Modularization can divide a complex problem into several simple problems to deal with. For example, your ability can only deal with a problem of 70 points at a time. Now there is a problem of 80 points, which is difficult to deal with at one time. You often need to write, pause, think for a while, and then write again until it is completed; On the contrary, if you adopt a modular approach to solve the problem, you can directly divide the 80 point problem into four 20 point problems. At this time, you only need to build a shelf so that the sum of the four 20 point modules can be equal to 80 points, and then deal with each 20 point problem. In fact, it also adheres to the top-down design style.
I usually divide components into four categories

  1. Intelligent component

  2. Puppet assembly

  3. Container assembly

  4. High order component

If the project uses Redux, the intelligent component is usually the component that is connected. It only processes the data logic of all sub components under the component; The style, the real DOM structure, is in the charge of the puppet component. It usually has a state function and occasionally has its own state, but even the state only deals with the logic related to page display; The container component is very simple. If a page is compared to a person, the container component is a person’s head, body, and limbs. Roughly classify the pages, which is usually written like this

//Body
<div className="body">{this.props.children}</div>

PS: why don’t container components be written directlydivAs mentioned above.

If the first three types of components are serving the page, the last component is a component dedicated to the component. Like high-order functions, high-order components take the modified components as parameters, and can also pass in other configuration parameters. Finally, an enhanced component, Redux, is returnedconnectIt is a high-level component, which is usually written as follows:

//High order component
const Hoc = props => WrapComponent => {
  return class extends Component {
    render() {
      return <WrapComponent {...props} />;
    }
  };
};
//Use
class WrapComponent extends Component{
  render(){
    return <div />
  }
}
export default Hoc()(WrapComponent)

Redux data stream

In Redux data flow management, there are many best practices in the industry. I’ll throw a brick here to attract jade.
I think the general page logic is not a very complex project. Simply use Redux, Redux thunk, Redux action is enough. If the request to be processed is very complex, in order to avoid callback hell, you can use Redux saga. Usually, when we distribute data from the top to the bottom, we need to connect based on a dimension, which is usually the route page. Now we have basically reached a consensus on the router, that is, the data status of the router is also a kind of Redux data, which is independent of the view. Therefore, it is a good practice to use react Redux router to combine router and redux.
In Redux, there is a controversial point about whether to put the page status in redux. Some people think that Redux should only store data, that is, the data in the background and some of the data stored in the foreground; However, I think that during the development of our page, the display logic of the page is usually very coupled with the background data. Maybe the state of a button and the color of an icon are related to the background data. If we forcibly split it, it will become a process. We need to process the background data in Redux first. After processing it, Then go to the intelligent component to process the internal state (page state) according to the Redux data, which is very troublesome and difficult to maintain. My own approach is that each process only corresponds to one action, and the internal part of this action processes different data according to different parameters until the page normally responds to this operation.

summary

In general, many of us, including myself, have given too many functions and responsibilities to the view layer, resulting in the value of Redux not being brought into play. There are various states running in the view, which is difficult to maintain in the later stage. This is undoubtedly putting the cart before the horse. Writing this summary is also some reflection on my recent project. I hope more people can discuss it together. Thank you.

Recommended Today

SQL exercise 20 – Modeling & Reporting

This blog is used to review and sort out the common topic modeling architecture, analysis oriented architecture and integration topic reports in data warehouse. I have uploaded these reports to GitHub. If you are interested, you can have a lookAddress:https://github.com/nino-laiqiu/TiTanI recorded a relatively complete development process in my hexo blog deployed on GitHub. You can […]