Skip to content
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

Merged
merged 6 commits into from
Sep 21, 2023

Conversation

tgolen
Copy link
Collaborator

@tgolen tgolen commented Sep 20, 2023

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's state.

The solution is to pass both the props and the state 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

render(<TestComponentWithOnyx markReadyForHydration={markReadyForHydration} onRender={onRender} />);
return waitForPromisesToResolve();
Copy link
Collaborator Author

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.

Comment on lines 252 to 259
const TestComponentWithOnyx = withOnyx({
testObject: {
key: `${ONYX_KEYS.COLLECTION.TEST_KEY}${collectionItemID}`,
},
testThing: {
key: ({testObject}) => `${ONYX_KEYS.COLLECTION.RELATED_KEY}${(testObject && testObject.id) || 0}`,
},
})(ViewWithCollections);
Copy link
Contributor

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!

Copy link
Collaborator Author

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
Comment on lines 99 to 100
const previousKey = Str.result(mapping.key, {...prevProps, ...prevState});
const newKey = Str.result(mapping.key, {...this.props, ...this.state});
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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
Comment on lines 246 to 247
const mappingPropNames = _.keys(mapOnyxToState);
const stateOnlyWithOnyxData = _.pick(this.state, mappingPropNames);
Copy link
Contributor

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});
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Comment on lines 279 to 289
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}`,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm lovin' it

Copy link
Contributor

@allroundexperts allroundexperts left a comment

Choose a reason for hiding this comment

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

Super work!

@tgolen tgolen changed the title Testing dependent keys [HOLD for App PR to be created] Allow infinite dependent keys when using withOnyx Sep 21, 2023
@tgolen tgolen self-assigned this Sep 21, 2023
@tgolen tgolen marked this pull request as ready for review September 21, 2023 00:56
@tgolen tgolen requested a review from a team as a code owner September 21, 2023 00:56
@melvin-bot melvin-bot bot requested review from jasperhuangg and removed request for a team September 21, 2023 00:56
@tgolen tgolen changed the title [HOLD for App PR to be created] Allow infinite dependent keys when using withOnyx Allow infinite dependent keys when using withOnyx Sep 21, 2023
Copy link
Contributor

@jasperhuangg jasperhuangg left a comment

Choose a reason for hiding this comment

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

nice stuff!

@jasperhuangg jasperhuangg merged commit 8031f94 into main Sep 21, 2023
3 checks passed
@tgolen tgolen deleted the tgolen-dependent-keys branch September 21, 2023 05:51
@tgolen
Copy link
Collaborator Author

tgolen commented Sep 21, 2023

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.

@chrispader
Copy link
Contributor

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 👍🏼

@tgolen
Copy link
Collaborator Author

tgolen commented Oct 9, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dependent keys are not working as expected when using withOnyx
4 participants