forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
react-native+0.75.2+026+fix-dropping-mutations-in-transactions.patch
67 lines (62 loc) · 2.97 KB
/
react-native+0.75.2+026+fix-dropping-mutations-in-transactions.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
diff --git a/node_modules/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/node_modules/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp
index 572fb3d..0efa1ed 100644
--- a/node_modules/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp
+++ b/node_modules/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp
@@ -468,7 +468,7 @@ void Binding::schedulerDidFinishTransaction(
mountingTransaction->getSurfaceId();
});
- if (pendingTransaction != pendingTransactions_.end()) {
+ if (pendingTransaction != pendingTransactions_.end() && pendingTransaction->canMergeWith(*mountingTransaction)) {
pendingTransaction->mergeWith(std::move(*mountingTransaction));
} else {
pendingTransactions_.push_back(std::move(*mountingTransaction));
diff --git a/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.cpp b/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.cpp
index d7dd1bc..d95d779 100644
--- a/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.cpp
+++ b/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.cpp
@@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
+#include <set>
+
#include "MountingTransaction.h"
namespace facebook::react {
@@ -54,4 +56,21 @@ void MountingTransaction::mergeWith(MountingTransaction&& transaction) {
telemetry_ = std::move(transaction.telemetry_);
}
+bool MountingTransaction::canMergeWith(MountingTransaction& transaction) {
+ std::set<Tag> deletedTags;
+ for (const auto& mutation : mutations_) {
+ if (mutation.type == ShadowViewMutation::Type::Delete) {
+ deletedTags.insert(mutation.oldChildShadowView.tag);
+ }
+ }
+
+ for (const auto& mutation : transaction.getMutations()) {
+ if (mutation.type == ShadowViewMutation::Type::Create && deletedTags.contains(mutation.newChildShadowView.tag)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace facebook::react
diff --git a/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.h b/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.h
index 277e9f4..38629db 100644
--- a/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.h
+++ b/node_modules/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.h
@@ -85,6 +85,14 @@ class MountingTransaction final {
*/
void mergeWith(MountingTransaction&& transaction);
+ /*
+ * Checks whether the two transactions can be safely merged. Due to
+ * reordering of mutations during mount, the sequence of
+ * REMOVE -> DELETE | CREATE -> INSERT (2 transactions) may get changed to
+ * INSERT -> REMOVE -> DELETE and the state will diverge from there.
+ */
+ bool canMergeWith(MountingTransaction& transaction);
+
private:
SurfaceId surfaceId_;
Number number_;