Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

[WIP] Fixes for ReactNative on Fiber #528

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions backend/getData.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ function getData(element: Object): DataType {
}
}

if (typeof element.setNativeProps === 'function') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: this depends on how we expose host instances in the end.

It might be that we'll just expose this from RN renderer instead, and it will have to inject setNativeProps(tag) just like it does with resolveStyle().

// For editing styles in RN
updater = {
setNativeProps(nativeProps) {
element.setNativeProps(nativeProps);
},
};
}

return {
nodeType,
type,
Expand Down
23 changes: 21 additions & 2 deletions backend/getDataFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ function getDataFiber(fiber: Object, getOpaqueNode: (fiber: Object) => Object):
break;
case HostComponent:
nodeType = 'Native';
name = fiber.type;
name = typeof fiber.type === 'string' ?
fiber.type :
// Necessary for React Native Fiber if host types are not strings.
// https://github.com/facebook/react/pull/9013
getDisplayName(fiber.type);
props = fiber.memoizedProps;
if (
typeof props.children === 'string' ||
Expand All @@ -90,6 +94,14 @@ function getDataFiber(fiber: Object, getOpaqueNode: (fiber: Object) => Object):
} else {
children = [];
}
if (typeof fiber.stateNode.setNativeProps === 'function') {
// For editing styles in RN
updater = {
setNativeProps(nativeProps) {
fiber.stateNode.setNativeProps(nativeProps);
},
};
}
break;
case HostText:
nodeType = 'Text';
Expand Down Expand Up @@ -133,7 +145,14 @@ function getDataFiber(fiber: Object, getOpaqueNode: (fiber: Object) => Object):
}

function setInProps(fiber, path: Array<string | number>, value: any) {
fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
const inst = fiber.stateNode;
fiber.pendingProps = copyWithSet(inst.props, path, value);
if (fiber.alternate) {
// We don't know which fiber is the current one because DevTools may bail out of getDataFiber() call,
// and so the data object may refer to another version of the fiber. Therefore we update pendingProps
// on both. I hope that this is safe.
fiber.alternate.pendingProps = fiber.pendingProps;
}
fiber.stateNode.forceUpdate();
}

Expand Down
19 changes: 12 additions & 7 deletions backend/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@
*/
'use strict';

type CompositeUpdater = {
setInProps: ?(path: Array<string>, value: any) => void,
setInState: ?(path: Array<string>, value: any) => void,
setInContext: ?(path: Array<string>, value: any) => void,
forceUpdate: ?() => void,
};

type NativeUpdater = {
setNativeProps: ?(nativeProps: {[key: string]: any}) => void,
};

export type DataType = {
nodeType: 'Native' | 'Wrapper' | 'NativeWrapper' | 'Composite' | 'Text' | 'Portal' | 'Empty',
type: ?(string | AnyFn),
Expand All @@ -22,13 +33,7 @@ export type DataType = {
context: ?Object,
children: ?(string | Array<OpaqueNodeHandle>),
text: ?string,
updater: ?{
setInProps: ?(path: Array<string>, value: any) => void,
setInState: ?(path: Array<string>, value: any) => void,
setInContext: ?(path: Array<string>, value: any) => void,
// setState: ?(newState: any) => void,
forceUpdate: ?() => void,
},
updater: ?(CompositeUpdater | NativeUpdater),
publicInstance: ?Object,
};

Expand Down
34 changes: 26 additions & 8 deletions plugins/ReactNativeStyle/setupBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,20 @@ function renameStyle(agent, id, oldName, newName, val) {
var data = agent.elementData.get(id);
var newStyle = {[newName]: val};
if (!data || !data.updater || !data.updater.setInProps) {
var el = agent.reactElements.get(id);
if (el && el.setNativeProps) {
el.setNativeProps({ style: newStyle });
if (data && data.updater && data.updater.setNativeProps) {
data.updater.setNativeProps({ style: newStyle });
} else {
console.error('Unable to set style for this element... (no forceUpdate or setNativeProps)');
// <hack>
// We can remove this when we stop supporting RN versions
// before https://github.com/facebook/react-devtools/pull/528.
// Newer versions use `updater.setNativeProps` instead.
var el = agent.reactElements.get(id);
if (el && el.setNativeProps) {
el.setNativeProps({ style: newStyle });
} else {
console.error('Unable to set style for this element... (no forceUpdate or setNativeProps)');
}
// </hack>
}
return;
}
Expand Down Expand Up @@ -84,11 +93,20 @@ function setStyle(agent, id, attr, val) {
var data = agent.elementData.get(id);
var newStyle = {[attr]: val};
if (!data || !data.updater || !data.updater.setInProps) {
var el = agent.reactElements.get(id);
if (el && el.setNativeProps) {
el.setNativeProps({ style: newStyle });
if (data && data.updater && data.updater.setNativeProps) {
data.updater.setNativeProps({ style: newStyle });
} else {
console.error('Unable to set style for this element... (no forceUpdate or setNativeProps)');
// <hack>
// We can remove this when we stop supporting RN versions
// before https://github.com/facebook/react-devtools/pull/528.
// Newer versions use `updater.setNativeProps` instead.
var el = agent.reactElements.get(id);
if (el && el.setNativeProps) {
el.setNativeProps({ style: newStyle });
} else {
console.error('Unable to set style for this element... (no forceUpdate or setNativeProps)');
}
// </hack>
}
return;
}
Expand Down