Compare memoized props in functional component branch
The functional component branch is a bit special since it has sCU in it. The class component branch actually already covers this in a bit convoluted way. I will next replicate this check in each other branch.
Sebastian Markbage committed
Dec 20, 2016 at 22:41 UTC
5a32fdb8e5e41d23cf6b2590d50c5ec1e1d53b21
1 file changed
+18
-11
src/renderers/shared/fiber/ReactFiberBeginWork.js
+18
-11
@@ -174,26 +174,33 @@ module.exports = function<T, P, I, TI, C, CX>(
174
175
function updateFunctionalComponent(current, workInProgress) {
176
var fn = workInProgress.type;
177
- var props = workInProgress.pendingProps;
178
- var context = getMaskedContext(workInProgress);
177
+ var nextProps = workInProgress.pendingProps;
178
180
- // TODO: Disable this before release, since it is not part of the public API
181
- // I use this for testing to compare the relative overhead of classes.
182
- if (typeof fn.shouldComponentUpdate === 'function') {
183
- if (workInProgress.memoizedProps !== null) {
184
- if (!fn.shouldComponentUpdate(workInProgress.memoizedProps, props)) {
185
- return bailoutOnAlreadyFinishedWork(current, workInProgress);
186
- }
179
+ const memoizedProps = workInProgress.memoizedProps;
180
+ if (hasContextChanged()) {
181
+ // Normally we can bail out on props equality but if context has changed
182
+ // we don't do the bailout and we have to reuse existing props instead.
183
+ if (nextProps === null) {
184
+ nextProps = current && current.memoizedProps;
185
}
186
+ } else if (nextProps === null || memoizedProps === nextProps || (
187
+ // TODO: Disable this before release, since it is not part of the public API
188
+ // I use this for testing to compare the relative overhead of classes.
189
+ typeof fn.shouldComponentUpdate === 'function' &&
190
+ !fn.shouldComponentUpdate(memoizedProps, nextProps)
191
+ )) {
192
+ return bailoutOnAlreadyFinishedWork(current, workInProgress);
193
}
194
195
+ var context = getMaskedContext(workInProgress);
196
+
197
var nextChildren;
198
199
if (__DEV__) {
200
ReactCurrentOwner.current = workInProgress;
194
- nextChildren = fn(props, context);
201
+ nextChildren = fn(nextProps, context);
202
} else {
196
- nextChildren = fn(props, context);
203
+ nextChildren = fn(nextProps, context);
204
}
205
reconcileChildren(current, workInProgress, nextChildren);
206
return workInProgress.child;