-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Conversation
Can I ask you to rebuild |
@gaearon done |
Great. I’m going to look at this and a few other PRs in a batch later next week. |
@gaearon
I believe this case can be handled too, it must be somewhere in agent/backend code, but I don't investigate this part yet. On the other hand if user pass getter as prop do we really need to care about it's deferred eval, cause probably it's value will be used inside component logic immediately. |
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.
looks great!
frontend/DataView/Getter.js
Outdated
} | ||
|
||
render() { | ||
return (<div style={style} onClick={this.handleClick.bind(this)}>(…)</div>); |
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.
nit: don't need the parens
yeah I don't think we have to worry about the deferred eval of passing the getter in directly (and indeed I don't think we'd be able to) |
Let’s do this then? It would help me if you also added some screenshots so I knew better how to test this. |
@gaearon k, Will do it later this week |
@gaearon @jaredly Updated PR, was not so trivial as I expect. Spend some time dealing with updates logic on Node component and store decorator. To test:
|
frontend/Store.js
Outdated
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 comment
The 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 comment
The 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 comment
The 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:
var newProps = assign({}, props);
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
shouldComponentUpdate(nextProps: PropsType) { return nextProps !== this.props; }
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explaining, this makes sense.
Just a heads up: I'm in the middle of some other work but I'll get back to this as soon as I can. Likely within one or two weeks. |
How does this work with updates? Say I have a getter that is backed by an instance field. That field changes. Is there any way to re-evaluate the getter? Should there be? |
I think ideally there should be a way to re-evaluate the getter so that you don’t end up with stale values forever. What do you think? |
Let's take this example from #390 (comment): var proto = {
get upperName() { return this.name.toUpperCase()}
};
var instance = Object.create(proto);
instance.name = 'Foo'; When I am editing it, here is what I see: Why does the getter disappear? |
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.
Let’s figure out a strategy for re-evaluating a getter, and also fix the issue I described in gif.
(Thanks for your work on this. I’m sorry I haven’t been very responsive lately. I think this is a good start but let’s ensure the feature works well in most cases so that people learn to trust it. Otherwise, even if we fix it in the future, people will avoid it because it did’t match their expectations before.) Note I’ve pushed to your branch so you shouldn’t worry about merging with master. |
@gaearon I will check about hiding, must some caveat with object nesting About re-evaluating: don't think we need worry at all due to unidirectional data flow nature and immutable state. If user change something what means we get new set of props and new eval buttons (...) Where is no way to for getter value to be staled - it's not evaluated yet or it's correct and actual. I will check it next as I back to code |
Interesting. I tried a simple example where getter and setter write to a backing property, like let obj = {
get lol() {
return this._lol;
}
set lol(val) {
this._lol = val;
}
} and I don't think editing worked for me. |
@gaearon I take a look, seems updates on backend side affects getters not the way I expect. Will look further on this issues |
…tters # Conflicts: # frontend/PropVal.js
@gaearon ping Also your example with update object with getter defined on prototype should be fine |
Cool! I’ll review when I get the time. |
…tters # Conflicts: # agent/Agent.js # frontend/Store.js
@gaearon Merge master and resolve conflict, also I've added samples to prop tester mini-app |
agent/dehydrate.js
Outdated
@@ -165,4 +173,11 @@ function dehydrate(data: Object, cleaned: Array<Array<string>>, path?: Array<str | |||
} | |||
} | |||
|
|||
function isPropertyGetter(obj, prop) { | |||
/* eslint-disable no-proto */ | |||
const descriptor = Object.getOwnPropertyDescriptor(obj.hasOwnProperty(prop) ? obj : obj.__proto__, prop); |
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!
When I wonder if maybe it's better to keep it around, but show a |
@zinoviev What are your thoughts on this? I wonder if we can look at how this compares to how Chrome displays getters. |
@gaearon I'm not sure it's actually intended, perhaps just the way devtools works. Getter doesn't have to be pure functions:
So it's easy to make the outdated value in this case and if you want real value you must print object on console or add new watch. As far I remember, in react devtools on any edit we get a new set of props every time user edit anything - immutable state and unidirectional flow for the rescue. So I think react devtools have a more reliable implementation for now. I don't like refresh buttons, imo explicit is better than implicit and neither chrome has ones. We can try to implement chrome like behavior for single object updates, but thinks it's out of scope for this PR as I don't actually touch updates passing mechanism and it can be major changes, not sure if it worths. |
I'm mostly concerned about this making edits inside large trees unusable if any parent is a getter. I understand that getter could mutate other objects but limiting this to the same object would make sure the feature doesn't break existing workflows for people. It's a compromise. |
@gaearon Like this? |
This looks like it! Apologies, I don't have the time to review right now but we'll try to get back to it. There's just too many things going on at the same time. |
@gaearon ping, I've make requested changes and some more additions |
I'm sorry I haven't looked yet. We got a lot of changes through but this one is complex enough that it keeps slipping through the cracks. I'm adding it to my todos next week, and will try to review. Thank you again for working on this. |
@gaearon ping, any chances for review? |
So what's with the PR? Problem still actual. |
Can this get reviewed? It's breaking on an important part of my code that I'd really like to inspect. |
React DevTools has been rewritten and recently launched a new version 4 UI 🎉 The source code for this rewrite was done in a separate repository and is being merged into the main React repo. Thank you for taking the time to contribute to this extension 🙇♂️ Because this PR is for the version code base, I am closing it. If you'd like to contribute to the new extension, please visit the new repository. |
PR for #390