-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Deferred object getters evaluation #569
Changes from 10 commits
a2877ae
3db945c
e9f2c02
9158344
8fffed5
6275882
71d9c3d
c3da494
e7d6e0f
ce60b1c
b4cd08f
b59ebf5
a64d1c9
c5d6eb2
0d2565a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @flow | ||
*/ | ||
'use strict'; | ||
var React = require('react'); | ||
|
||
class Getter extends React.Component { | ||
handleClick() { | ||
this.context.onEvalGetter(this.props.path); | ||
} | ||
|
||
constructor(props: Object) { | ||
super(props); | ||
} | ||
|
||
render() { | ||
return <div style={style} onClick={this.handleClick.bind(this)}>(…)</div>; | ||
} | ||
} | ||
|
||
const style = { | ||
'cursor': 'pointer', | ||
}; | ||
|
||
Getter.propTypes = { | ||
data: React.PropTypes.any, | ||
path: React.PropTypes.array, | ||
}; | ||
|
||
Getter.contextTypes = { | ||
onEvalGetter: React.PropTypes.func, | ||
}; | ||
|
||
module.exports = Getter; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,7 @@ const DEFAULT_PLACEHOLDER = 'Search (text or /regex/)'; | |
* - toggleCollapse | ||
* - toggleAllChildrenNodes | ||
* - setProps/State/Context | ||
* - evalGetter | ||
* - makeGlobal(id, path) | ||
* - setHover(id, isHovered, isBottomTag) | ||
* - selectTop(id) | ||
|
@@ -176,6 +177,7 @@ class Store extends EventEmitter { | |
this._bridge.on('mount', (data) => this._mountComponent(data)); | ||
this._bridge.on('update', (data) => this._updateComponent(data)); | ||
this._bridge.on('unmount', id => this._unmountComponent(id)); | ||
this._bridge.on('evalgetterresult', (data) => this._setGetterValue(data)); | ||
this._bridge.on('setInspectEnabled', (data) => this.setInspectEnabled(data)); | ||
this._bridge.on('select', ({id, quiet}) => { | ||
this._revealDeep(id); | ||
|
@@ -423,6 +425,10 @@ class Store extends EventEmitter { | |
this._bridge.send('setContext', {id, path, value}); | ||
} | ||
|
||
evalGetter(id: ElementID, path: Array<string>) { | ||
this._bridge.send('evalGetter', {id, path}); | ||
} | ||
|
||
makeGlobal(id: ElementID, path: Array<string>) { | ||
this._bridge.send('makeGlobal', {id, path}); | ||
} | ||
|
@@ -698,6 +704,17 @@ class Store extends EventEmitter { | |
this._nodesByName = this._nodesByName.set(node.get('name'), this._nodesByName.get(node.get('name')).delete(id)); | ||
} | ||
} | ||
|
||
_setGetterValue(data: DataType) { | ||
var node = this._nodes.get(data.id); | ||
var props = node.get('props'); | ||
var last = data.path.length - 1; | ||
var propObj = data.path.slice(0, last).reduce((obj_, attr) => obj_ ? obj_[attr] : null, props); | ||
propObj[data.path[last]] = data.value; | ||
var newProps = assign({}, props); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Props must be new object or bounded Node wont rerenders There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like tangential unrelated issue (worth raising). Why is this specific to getters (and not just any prop mutations)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reason why - you don't mutate original props on requesting getter value. If you edit some prop(for example text) in devtools, it forwards changes to original page component. Original component props mutates and new set of props goes back to devtools store, immutable collection recreates, UI rerenders etc But on requesting getter value we pass just singular value and do not make any changes to original prop. So this part of code needed to make frontend store's data in sync and refresh UI nicely. But why do we need this line: Data stored in immutable map on store._nodes But node props is not immutable map, it just a plain JS object. In Node.js (component node on left panel) where is SCU check
So if we just swap value inside this object UI wont refreshes correclty There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for explaining, this makes sense. |
||
this._nodes = this._nodes.setIn([data.id, 'props'], newProps); | ||
this.emit(data.id); | ||
} | ||
} | ||
|
||
module.exports = Store; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this check one level deep? Could it be on
__proto__.__proto__
,__proto__.__proto__.__proto__
, etc? Do we need a loop here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My fail, will fix asap!