-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow infinite dependent keys when using withOnyx #355
Conversation
render(<TestComponentWithOnyx markReadyForHydration={markReadyForHydration} onRender={onRender} />); | ||
return waitForPromisesToResolve(); |
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.
I also found that the test wouldn't pass without this being added, which I think is normal. I'm not sure why it was removed as it existed when the test was originally written.
tests/unit/withOnyxTest.js
Outdated
const TestComponentWithOnyx = withOnyx({ | ||
testObject: { | ||
key: `${ONYX_KEYS.COLLECTION.TEST_KEY}${collectionItemID}`, | ||
}, | ||
testThing: { | ||
key: ({testObject}) => `${ONYX_KEYS.COLLECTION.RELATED_KEY}${(testObject && testObject.id) || 0}`, | ||
}, | ||
})(ViewWithCollections); |
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.
Nice job updating these tests. Can you maybe add another key which is dependent on testThing
? This will verify that n
layer of nesting can be avoided by this flattened out structure!
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.
Yeah, that's a great idea. I will add that!
lib/withOnyx.js
Outdated
const previousKey = Str.result(mapping.key, {...prevProps, ...prevState}); | ||
const newKey = Str.result(mapping.key, {...this.props, ...this.state}); |
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.
Adding this.state
directly might lead the exposure of some state properties like this.state.loading
that shouldn't be visible to the end user. Do you think its a deal breaker?
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.
It's probably not a deal-breaker (until someone starts abusing it), but it would be easy to also omit all keys from the state which aren't part of the mappings. I can add that.
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.
That's perfect!
lib/withOnyx.js
Outdated
const mappingPropNames = _.keys(mapOnyxToState); | ||
const stateOnlyWithOnyxData = _.pick(this.state, mappingPropNames); |
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.
Would be better to move this to another function since its being used at top as well.
lib/withOnyx.js
Outdated
const key = Str.result(mapping.key, {...this.props, ...this.state}); | ||
const mappingPropNames = _.keys(mapOnyxToState); | ||
const stateOnlyWithOnyxData = _.pick(this.state, mappingPropNames); | ||
const key = Str.result(mapping.key, {...this.props, ...stateOnlyWithOnyxData}); |
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.
Probably, this can also go into that same function.
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.
Sure, good idea. I've updated it to DRY up this logic and move it into a simple function defined at the top of the module.
tests/unit/withOnyxTest.js
Outdated
staticObject: { | ||
key: `${ONYX_KEYS.COLLECTION.STATIC}1`, | ||
}, | ||
testThing: { | ||
key: ({testObject}) => `${ONYX_KEYS.COLLECTION.RELATED_KEY}${(testObject && testObject.id) || 0}`, | ||
dependentObject: { | ||
key: ({staticObject}) => `${ONYX_KEYS.COLLECTION.DEPENDS_ON_STATIC}${(staticObject && staticObject.id) || 0}`, | ||
}, | ||
multiDependentObject: { | ||
key: ({dependentObject}) => `${ONYX_KEYS.COLLECTION.DEPENDS_ON_DEPENDS_ON_STATIC}${(dependentObject && dependentObject.id) || 0}`, | ||
}, | ||
extremeMultiDependentObject: { | ||
key: ({multiDependentObject}) => `${ONYX_KEYS.COLLECTION.DEPENDS_ON_DEPENDS_ON_DEPENDS_ON_STATIC}${(multiDependentObject && multiDependentObject.id) || 0}`, |
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.
I'm lovin' it
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.
Super work!
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.
nice stuff!
Unfortunately, when tested in App, this caused major performance problems that locks up the browser. So, while it is a great change, I guess there are some other considerations that need to be made for this to be viable. CC @chrispader @kidroca @hannojg I'd love to brainstorm with you guys on this one. |
@tgolen sorry that i didn't respond yet. i'm gonna try to look into this issue this week, if nothing has changed 👍🏼 |
Thanks, Chris! I redid the original PR in #385 and I am unable to reproduce any of the original performance problems, so I don't know that we need to do anything more yet at this point. |
Details
I found that the dependent keys weren't being loaded because we were only passing
props
to the key functions. This won't contain the already loaded Onyx data because that data is only stored in the HOC'sstate
.The solution is to pass both the
props
and thestate
to the key functions.There were a couple more fixes I had to do to ensure multiple levels of depencies are resolved as expected.
Related Issues
Fixes Expensify/App#27906
Automated Tests
All covered by unit tests
Linked PRs
TBD