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

add ability to use custom state persistence fn #21

Merged
merged 11 commits into from
May 16, 2019
Merged

add ability to use custom state persistence fn #21

merged 11 commits into from
May 16, 2019

Conversation

vonovak
Copy link
Member

@vonovak vonovak commented Apr 17, 2019

motivation: our app, historically, does not always have JSON-serializable navigation params.

Some of our params are instances of classes that, when you do JSON.stringify(param), the call does not throw, but the resulting JSON loses some information and the original instance cannot be recovered. So it seems like the state was serialized successfully, but after a reload, the screens do not have their correct nav params, causing a crash.

I'd like to be able to specify custom serialization fn so that we can serialize only the state we want.

As a side effect, I also added loadNavigationState which helps remove dependency on AsyncStorage (#17) and allows to modify the recovered nav state object.

const {
navigation,
screenProps,
persistNavigationState,
Copy link
Member Author

@vonovak vonovak Apr 17, 2019

Choose a reason for hiding this comment

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

I'm not sure if this is a good thing, but if you keep the old diff, tests fail

@vonovak vonovak marked this pull request as ready for review April 17, 2019 15:22
if (!persistenceKey) {
return;
}
await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState));
Copy link
Member

Choose a reason for hiding this comment

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

We should probably also move the require statement inside here to avoid the warning from RN. cc @brentvatne

Copy link
Member Author

Choose a reason for hiding this comment

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

I added these functions so that the code is backward compatible, but I could as well remove the default value for persistNavigationState, loadNavigationState and the persistenceKey prop, to remove the AsyncStorage dependency altogether. That will be breaking, but in the docs, the api is described as experimental and it is explicitly said the api may change in future, so it's fine, imho.

Copy link
Member

@brentvatne brentvatne Apr 23, 2019

Choose a reason for hiding this comment

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

yeah i think it's fine to remove it, and in the docs we can provide some default implementation for people that use asyncstorage

@@ -227,7 +239,7 @@ export default function createNavigationContainer(Component) {
startupState = Component.router.getStateForAction(action);
}

// Pull persisted state from AsyncStorage
// Pull user-provided persisted state
if (startupStateJSON) {
try {
startupState = JSON.parse(startupStateJSON);
Copy link
Member Author

@vonovak vonovak Apr 25, 2019

Choose a reason for hiding this comment

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

currently loadNavigationState is expected to return a json string and we call JSON.parse on that string here to get an object.

I'd vote for loadNavigationState returning an object instead of a string (It'd just require moving this JSON.parse into the user-provided function).

From a developer perspective, for whatever reason, if I want to manipulate the state, I'd prefer to work with an object and return that object, rather than converting a json string (from asyncStorage) to an object, then manipulate what I need and then stringifying that (which may not work fi I need to insert something non-stringifyable), passing it to react-navigation which would call JSON.parse again. wdyt @brentvatne ?

Copy link
Member Author

@vonovak vonovak Apr 26, 2019

Choose a reason for hiding this comment

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

I went ahead and did that in 6d9510b

Copy link
Member

Choose a reason for hiding this comment

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

that seems totally reasonable @vonovak! apologies for the slow reply

@brentvatne
Copy link
Member

lgtm! a couple things we can do as followup:

@vonovak vonovak changed the title add ability to use custom state persistence fn [WIP] add ability to use custom state persistence fn May 1, 2019
@vonovak vonovak changed the title [WIP] add ability to use custom state persistence fn add ability to use custom state persistence fn May 2, 2019
@vonovak
Copy link
Member Author

vonovak commented May 2, 2019

if persistenceKey is provided, let's warn the user that this was removed and refer them to that docs page

good point, added in c59cc01 - feel free to change the message if something is missing

I made another change in 0fa5e46 that handles the case when loadNavigationState throws - I figured we should catch that situation

I'll open a PR for the docs shortly

@brentvatne
Copy link
Member

lgtm!

@brentvatne
Copy link
Member

let's ship this soon :> should i do it tomorrow @vonovak?

@vonovak
Copy link
Member Author

vonovak commented May 16, 2019

The PR is good for merge, so feel free to ship as you see fit. The docs react-navigation/react-navigation.github.io#425 update is also ready.

@brentvatne brentvatne merged commit 0cd6fd2 into react-navigation:master May 16, 2019
@brentvatne
Copy link
Member

it's live!

@vonovak vonovak deleted the customStatePersistence branch June 14, 2019 07:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants