In-depth explanation of the global status of WeChat applet

In-depth explanation of the global status of WeChat applet

Preface

In WeChat applet, you can use globalData of App.js as an intermediate bridge to pass the information between Page and Component, including between pages, between pages and components, and between components. However, we cannot know the changes under globalData in time. In the official default case of creating a new applet, the network operation of obtaining UserInfo is delayed, and a lot of unnecessary code is written for this. Even the official cases have this situation, I believe you will encounter similar situations during development. This article will introduce how to solve this kind of problem.

Demand Analysis

I believe the following situations are common operations we perform without global state management:

  • In the OnLoad and Attached lifecycle hook functions of Page and Component, some existing properties are assigned from the globalData of App to the data in the page or component.
  • At the very beginning, there are some asynchronous network requests, and the data obtained is used globally. At the beginning, the globalData may not have relevant attributes until the request is successful, and the relevant attributes are added to the globalData. At this time, the assignment operation of the Page from the globalData may have been completed, but it is undefined. Therefore, further judgment is needed before assigning it to the Page and Component. If it's just one or two, it's very simple, but if multiple pages or multiple variables need to be assigned, I think you will refuse and look for lazy ways.
  • Some variables assigned from globalData in pages and components are not only used for judgment and display, but we may also need to change the value of the variable based on user interaction. In this case, the same variables in other pages and other components also need to be changed uniformly.

In the above situation, we can put forward the following requirements:

  1. When the page or component is initially loaded, get and assign the required properties of the page or component from globalData as soon as possible.
  2. Obtain changes to a certain attribute of globalData in a timely manner and perform some subsequent related operations
  3. When changing the value of Page or Component, other pages and components also make the same changes.

Below is the original code required

// app.js
App({
 globalData: {
  userInfo: null
 },
 onLaunch(){
  wx.getSetting({
   success: res => {
    if(res.authSetting['scope.userInfo']){
     wx.getUserInfo({
      success: res => {
       this.globalData.userInfo = res.userInfo
       // Requirement 2
       if (this.userInfoReadyCallback) {
        // The existence of this callback function means that the page has executed onLoad
        // And userInfo is not obtained and assigned to the data of the page // Execute this callback function and assign it to the corresponding page this.userInfoReadyCallback(res)
       }
      }
     })
    }
   }
  })
 }
})
// Pages/index/index.js
const app = getApp()
Page({
 // ...
 onLoad(options){
  // Requirement 1
  const userInfo = app.globalData.userInfo
  userInfo && this.setData({useInfo})
  // Requirement 2
  // If app.globalData.userInfo is not obtained
  // means the callback function of wx.getUserInfo has not been executed yet // add a callback function to the app, bind this to the callback function userInfo || app.userInfoReadyCallback = res => {
   this.setData({
    userInfo: res.userInfo
   })
   delete app.userInfoReadyCallback
  }
 }
})

This is the code of the official mini program case. I only made a few modifications. Here it only shows requirement 2. The globalData attribute changes from nothing to sometimes executing the callback function set by the page, but it does not implement the execution of the callback function every time. The code of requirement 3 is more complicated and is not shown here.

We can think about what codes are necessary to implement the above requirements. It can be found that requirements 1 and 3 mainly require the use of the this.setData method when the page, component initialization, and globalData properties are changed, but the instance pointed to by this is different each time. Requirement 2 is that there should be a callback function, and the this of the callback function should also point to the corresponding instance, and these callback functions should be executed when the globalData property is changed.
From the perspective of time points, we have two, one is when the page and component are initialized, and the other is when the globalData property changes. For the first time point, we can consider the hook functions of the applet's life cycle, onLoad and attached, and execute the this.setData operation at these two time points. The changes of globalData attributes are all caused by our own initiative or user events. That is, this operation can be regarded as an event for a certain attribute of globalData, and after this event occurs, some written callback functions are executed.

From the perspective of operation objects, they are basically instances of this of pages and components, as well as app.globalData.

Theoretical summary of demand

In summary, we can automatically perform this.setData (without doing it manually) and save this (used to point to the corresponding instance when the event is executed) during initialization, store the corresponding callback function as an event (an event is an unexecuted function), and actively trigger this event when needed. Then you can see that throughout the entire process, we need a variable that spans app, page, and component to hijack the initialization hook function, perform automatic assignment, store corresponding events, and expose an event-triggered interface.

What you learn from books is always shallow, you must practice it to know it well

Seeing this, I believe you already have a certain understanding of global state management, so how to implement it? Here, I want to emphasize that if you have a certain understanding of this after reading this article, and the ideas I mentioned, then you must try to implement the code yourself. Whether it is good or bad, it is always better than not implementing it, and you may gain more from your own implementation. The above case below shows a simple implementation code to give an idea for those who don’t understand it very well. Next time I will write an explanation of the relevant code implementation, there should be one.

// app.js
class Store {
 constructor(app){
 this['event'] = {}
 this.app = app
 }
 autoSet(globalData, instance){
 const instanceData = {}
 for (let prop of globalData){
  instanceData[prop] = this.app.globalData[prop]
  const callBack = (newValue) => {
  instance.setData({[prop]: newValue})
  instance.watch[prop] && instance.watch[prop].call(instance, newValue)
  }
  this.addEvent(prop, callBack)
  instance.setData(instanceData)
  callBack(instanceData[prop])
  delete instance.watch
  delete instance.globalData
 }
 }
 addEvent(eventName, callBack){
 this.event[eventName] = this.event[eventName] || []
 this.event[eventName].push(callBack)
 }
 dispatch(eventName, newValue){
 this.app.globalData[eventName] = newValue
 this.event[eventName] && this.event[eventName].forEach(item => item(newValue))
 }
}

App({
 globalData: {
  userInfo: null
 },
 onLaunch(){
  // Create a new instance and save it to the mini program app for global call this.store = new Store(this)
  wx.getSetting({
   success: res => {
    if(res.authSetting['scope.userInfo']){
     wx.getUserInfo({
      success: res => {
       // After getting userInfo, trigger the event this.store.dispatch('userInfo', res.userInfo)
      }
     })
    }
   }
  })
 }
})
// Pages/index/index.js
const app = getApp()
Page({
 // ...
 data: {
  userName: null
 },
 // The globalData array is used to automatically assign globalData: ['userInfo'],
 // Listen to the corresponding globalData attribute and set the callback function watch: {
  userInfo(userInfo){
  console.log('userInfo updated', this)
  this.setData({userName: userInfo.nickName})
  }
 },
 onLoad(options){
  // Pass in this globalData and instance, set the data required by the instance, and create the event app.store.autoSet(this.globalData, this)
  // Anything else you want to do...
 }
})

The above code does not hijack the hook function, but only executes the bound function additionally at the beginning of the function, and there is no operation to release the memory when the page is destroyed. There are still many areas that can be optimized, which will be explained next time.

Summarize

This is the end of this article about the global status of WeChat Mini Programs. For more relevant content about the global status of Mini Programs, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Use watch to share global status in WeChat applet

<<:  Listen directive example analysis in nginx

>>:  How to query duplicate data in mysql table

Recommend

Solution to garbled display of Linux SecureCRT

Let's take a look at the situation where Secu...

CSS3 speeds up and delays transitions

1. Use the speed control function to control the ...

How to use Docker to build enterprise-level custom images

Preface Before leaving get off work, the author r...

Why MySQL does not recommend deleting data

Table of contents Preface InnoDB storage architec...

Nodejs module system source code analysis

Table of contents Overview CommonJS Specification...

How to align text boxes in multiple forms in HTML

The form code is as shown in the figure. The styl...

Detailed explanation of HTML basics (Part 2)

1. List The list ul container is loaded with a fo...

Detailed steps for yum configuration of nginx reverse proxy

Part.0 Background The company's intranet serv...

Use iptables and firewalld tools to manage Linux firewall connection rules

Firewall A firewall is a set of rules. When a pac...

JavaScript implements AI tic-tac-toe game through the maximum and minimum algorithm

Without further ado, let’s run the screenshot dir...

Graphical explanation of the underlying principle of JavaScript scope chain

Table of contents Preface Scope 1. What is scope?...

Example of how to implement embedded table with vue+elementUI

During my internship in my senior year, I encount...

Detailed explanation of the use of MySQL sql_mode

Table of contents Preface sql_mode explained The ...