mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Improve setting props of the Interop Layer (#41942)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41942 Previously, every time a component was updated, we were passing all the props to the interoperated component. With this change, we are going to only pass the props that are changed. As a safety feature, if the new codepath is not able to detect the type of the prop properly, it will fall back to the previous behavior. ## Changelog: [Internal] - Only pass props to the interoperated component when they changes Reviewed By: sammy-SC Differential Revision: D51755764 fbshipit-source-id: 0185d2cceeab2a1e45b87d5a1e82ab06e00aa82d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
201d2d1fde
commit
b0982971c6
+87
-2
@@ -41,6 +41,8 @@ using namespace facebook::react;
|
||||
*/
|
||||
NSMutableArray<id<RCTBridgeMethod>> *_moduleMethods;
|
||||
NSMutableDictionary<NSString *, id<RCTBridgeMethod>> *_moduleMethodsByName;
|
||||
|
||||
NSDictionary<NSString *, id> *_oldProps;
|
||||
}
|
||||
|
||||
- (instancetype)initWithComponentData:(RCTComponentData *)componentData
|
||||
@@ -100,11 +102,13 @@ using namespace facebook::react;
|
||||
{
|
||||
if (props.isObject()) {
|
||||
NSDictionary<NSString *, id> *convertedProps = convertFollyDynamicToId(props);
|
||||
[_componentData setProps:convertedProps forView:view];
|
||||
NSDictionary<NSString *, id> *diffedProps = [self _diffProps:convertedProps];
|
||||
[_componentData setProps:diffedProps forView:view];
|
||||
|
||||
if ([view respondsToSelector:@selector(didSetProps:)]) {
|
||||
[view performSelector:@selector(didSetProps:) withObject:[convertedProps allKeys]];
|
||||
[view performSelector:@selector(didSetProps:) withObject:[diffedProps allKeys]];
|
||||
}
|
||||
_oldProps = convertedProps;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,4 +252,85 @@ using namespace facebook::react;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id> *)_diffProps:(NSDictionary<NSString *, id> *)newProps
|
||||
{
|
||||
NSMutableDictionary<NSString *, id> *diffedProps = [NSMutableDictionary new];
|
||||
|
||||
[newProps enumerateKeysAndObjectsUsingBlock:^(NSString *key, id newProp, __unused BOOL *stop) {
|
||||
id oldProp = _oldProps[key];
|
||||
if ([self _prop:newProp isDifferentFrom:oldProp]) {
|
||||
diffedProps[key] = newProp;
|
||||
}
|
||||
}];
|
||||
|
||||
return diffedProps;
|
||||
}
|
||||
|
||||
- (BOOL)_prop:(id)oldProp isDifferentFrom:(id)newProp
|
||||
{
|
||||
// Check for JSON types.
|
||||
// JSON types can be of:
|
||||
// * number
|
||||
// * bool
|
||||
// * String
|
||||
// * Array
|
||||
// * Objects => Dictionaries in ObjectiveC
|
||||
// * Null
|
||||
|
||||
// Check for NULL
|
||||
BOOL bothNil = !oldProp && !newProp;
|
||||
if (bothNil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL onlyOneNil = (oldProp && !newProp) || (!oldProp && newProp);
|
||||
if (onlyOneNil) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([self _propIsSameNumber:oldProp second:newProp]) {
|
||||
// Boolean should be captured by NSNumber
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self _propIsSameString:oldProp second:newProp]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self _propIsSameArray:oldProp second:newProp]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self _propIsSameObject:oldProp second:newProp]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Previous behavior, fallback to YES
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_propIsSameNumber:(id)first second:(id)second
|
||||
{
|
||||
return [first isKindOfClass:[NSNumber class]] && [second isKindOfClass:[NSNumber class]] &&
|
||||
[(NSNumber *)first isEqualToNumber:(NSNumber *)second];
|
||||
}
|
||||
|
||||
- (BOOL)_propIsSameString:(id)first second:(id)second
|
||||
{
|
||||
return [first isKindOfClass:[NSString class]] && [second isKindOfClass:[NSString class]] &&
|
||||
[(NSString *)first isEqualToString:(NSString *)second];
|
||||
}
|
||||
|
||||
- (BOOL)_propIsSameArray:(id)first second:(id)second
|
||||
{
|
||||
return [first isKindOfClass:[NSArray class]] && [second isKindOfClass:[NSArray class]] &&
|
||||
[(NSArray *)first isEqualToArray:(NSArray *)second];
|
||||
}
|
||||
|
||||
- (BOOL)_propIsSameObject:(id)first second:(id)second
|
||||
{
|
||||
return [first isKindOfClass:[NSDictionary class]] && [second isKindOfClass:[NSDictionary class]] &&
|
||||
[(NSDictionary *)first isEqualToDictionary:(NSDictionary *)second];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user