PureComponent in Fiber
Passes existing PureComponent tests
Andrew Clark committed
Oct 26, 2016 at 16:56 UTC
59c94648c485b60035e150fc5e79232c4d25960f
1 file changed
+35
-12
src/renderers/shared/fiber/ReactFiberClassComponent.js
+35
-12
@@ -25,6 +25,7 @@ var {
25
} = require('ReactFiberUpdateQueue');
26
var { isMounted } = require('ReactFiberTreeReflection');
27
var ReactInstanceMap = require('ReactInstanceMap');
28
+var shallowEqual = require('shallowEqual');
29
30
module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void) {
31
@@ -73,6 +74,28 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
74
},
75
};
76
77
+ function checkShouldComponentUpdate(workInProgress, oldProps, newProps, newState) {
78
+ const updateQueue = workInProgress.updateQueue;
79
+ if (oldProps === null || (updateQueue && updateQueue.isForced)) {
80
+ return true;
81
+ }
82
+
83
+ const instance = workInProgress.stateNode;
84
+ if (typeof instance.shouldComponentUpdate === 'function') {
85
+ return instance.shouldComponentUpdate(newProps, newState);
86
+ }
87
+
88
+ const type = workInProgress.type;
89
+ if (type.prototype && type.prototype.isPureReactComponent) {
90
+ return (
91
+ !shallowEqual(oldProps, newProps) ||
92
+ !shallowEqual(instance.state, newState)
93
+ );
94
+ }
95
+
96
+ return true;
97
+ }
98
+
99
function adoptClassInstance(workInProgress : Fiber, instance : any) : void {
100
instance.updater = updater;
101
workInProgress.stateNode = instance;
@@ -116,7 +139,6 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
139
// Called on a preexisting class instance. Returns false if a resumed render
140
// could be reused.
141
function resumeMountClassInstance(workInProgress : Fiber) : boolean {
119
- const instance = workInProgress.stateNode;
142
let newState = workInProgress.memoizedState;
143
let newProps = workInProgress.pendingProps;
144
if (!newProps) {
@@ -132,13 +154,12 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
154
// componentWillMount and before this componentWillMount? Probably
155
// unsupported anyway.
156
135
- const updateQueue = workInProgress.updateQueue;
136
-
137
- // If this completed, we might be able to just reuse this instance.
138
- if (typeof instance.shouldComponentUpdate === 'function' &&
139
- !(updateQueue && updateQueue.isForced) &&
140
- workInProgress.memoizedProps !== null &&
141
- !instance.shouldComponentUpdate(newProps, newState)) {
157
+ if (!checkShouldComponentUpdate(
158
+ workInProgress,
159
+ workInProgress.memoizedProps,
160
+ newProps,
161
+ newState
162
+ )) {
163
return false;
164
}
165
@@ -196,10 +217,12 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
217
newState = previousState;
218
}
219
199
- if (typeof instance.shouldComponentUpdate === 'function' &&
200
- !(updateQueue && updateQueue.isForced) &&
201
- oldProps !== null &&
202
- !instance.shouldComponentUpdate(newProps, newState)) {
220
+ if (!checkShouldComponentUpdate(
221
+ workInProgress,
222
+ oldProps,
223
+ newProps,
224
+ newState
225
+ )) {
226
// TODO: Should this get the new props/state updated regardless?
227
return false;
228
}