The component lifecycle is usually where our business logic begins. If the business scenario is complex and the component life cycle does not perform as expected, This may cause some weird business bugs that are extremely difficult to reproduce and fix. Component attached Lifecycle execution timesAccording to common understanding, except for the life cycle of moved/show/hide, which may be executed multiple times, Strictly speaking, the life cycle related to component loading, such as created, attached, ready, etc., should only be executed once for each component instance. But is this really the case? background The discovery of this problem comes from the error log of our mini program. I received a lot of errors like Cannot redefine property: isComponent. Cause Analysis Through the variable name, we can trace back to the way we defined it in the code: Component({ lifetimes: attached() { Object.defineProperty(this, 'isComponent', { enumerable: true, get() { return true }, }); }, }, }); It is easy to understand that the cause of this error is trying to redefine a non-configurable property of an object. For details, please refer to the description on MDN. But this definition is written in the attached lifecycle. Does it mean that the attached lifecycle of the component is triggered twice? Oh my God, how is this possible? Yes, it's that magical! Scene restoration This problem is not easy to reproduce, but by constantly simplifying and unraveling the problem, we finally found the root cause:
You can reproduce this scenario with the following code, or directly access the applet code snippet. page // page.js Page({ data: { showChild2: false, }, onChild1Attached() { this.setData({ showChild2: true }); }, }); <!-- page.wxml --> <child1 bind:attached="onChild1Attached"></child1> <child2 wx:if="{{ showChild2 }}"></child2> Subcomponent 1 Rendered together with the page, and when attached, notified the page to update the status and render subcomponent 2 through triggerEvent. //child1.js Component({ lifetimes: attached() { this.triggerEvent('attached'); }, }, }); <!-- child1.wxml --> <view>child1</view> Subcomponent 2 The attached lifecycle was executed twice, resulting in an error. //child2.js Component({ lifetimes: attached() { Object.defineProperty(this, 'isComponent', { enumerable: true, get() { return true }, }); }, }, }); <!-- child2.wxml --> <view>child2</view> Component ready life cycle execution timeThe official documentation of the mini program does not clearly give the execution order of the component life cycle, but by printing the log we can easily find out:
So, it seems that the order should be: created -> attached -> ready -> detached. But is this really the case? background For a period of time, customer service often reported that there was data stringing in our mini program. For example: Merchant A’s live broadcast showcases Merchant B’s products. Cause Analysis String data occurs in multiple scenarios. Considering that the data is pushed to the mini program via messages, it is ultimately suspected that the problem lies in WebSocket communication. On the mini program side, we encapsulate a WebSocket communication component, the core logic is as follows: // socket.js Component({ lifetimes: ready() { this.getSocketConfig().then(config => { this.ws = wx.connectSocket(config); this.ws.onMessage(msg => { const data = JSON.parse(msg.data); this.onReceiveMessage(data); }); }); }, detached() { this.ws && this.ws.close({}); }, }, methods: { getSocketConfig() { // Request socket connection configuration from the server return new Promise(() => {}); }, onReceiveMessage(data) { event.emit('message', data); }, }, }); Simply put, when the component is ready, a WebSocket connection is initialized and message push is listened, and then the connection is closed in the detached phase. It seems that there is no problem, so we can only infer the situation that may not be in line with common sense from the results. Data is out of order -> WebSocket message is out of order -> WebSocket is not closed properly -> close is wrong/detached is not executed/ready is executed after detached Scene restoration The actual business logic here is relatively complex, so it can only be verified through simplified code. Through continuous experimentation, we finally found that:
You can reproduce this scenario with the following code, or directly access the applet code snippet. page // page.js Page({ data: { showChild: true, }, onLoad() { this.setData({ showChild: false }); }, }); <!-- page.wxml --> <child wx:if="{{ showChild }}" /> Components When a component is destroyed when it is not ready, detached will be executed synchronously first, and then ready will be executed asynchronously. //child.js Component({ lifetimes: created() { console.log('created'); }, attached() { console.log('attached'); }, ready() { console.log('ready'); }, detached() { console.log('detached'); } }, }); expand Even if the initialization work is moved from the ready stage to the attached stage, as long as there is asynchronous operation, it is still possible that detached is executed before the asynchronous callback. Therefore, please do not fully trust the destruction operation during the detached phase of the component. SummarizeThis is the end of this article about the pitfalls of WeChat Mini Program component life cycle. For more relevant content on the mini program component life cycle, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: How to view the type of mounted file system in Linux
>>: How to modify the password of MySQL 5.1 and remotely log in to the MySQL database
This article shares MYSQL logs and backup and res...
Copy code The code is as follows: <object clas...
Idea imports an existing web project and publishe...
Preface These principles are summarized from actu...
Preface: I reinstalled win10 and organized the fi...
Table of contents 1. Form events 2. Mouse events ...
Overview I have recently started learning MySQL r...
Each web page has an address, identified by a URL...
Recently, we have been capturing SQL online for o...
Table of contents 1. Select database USE 2. Displ...
Table of contents tool Install the plugin Add a ....
Table of contents Two major categories of functio...
If you’re looking for inspiration for columnar web...
Table of contents 1. Anonymous slots 2. Named slo...
Table of contents 1. JS Object DOM –1, Function –...