Skip to content

[Onyx Audit] Remove initWithStoredValues from useOnyx #80091

@fabioh8010

Description

@fabioh8010

Coming from #71202.

In order to simplify useOnyx API (and consequently Onyx) let's work on proposing the removal of some configurations we think are anti-patterns / unnecessary at this point.

Last year @roryabraham drafted this proposal that can be found in this doc, but I will put it below in case you don't have access. We should review the proposal, adjust if necessary and post it.

Original proposal from Rory

Proposal: Introduce RAM-only Onyx keys.

Background

react-native-onyx is a very versatile state management library that is the beating heart of our front-end. It largely relies on a publisher-subscriber (PubSub) pattern to propagate data across various front-end UI components. Furthermore, one of the driving principles of Onyx is supporting a snappy, optimistic, offline-first approach that couples data storage with state management.

Furthermore, we have built systems in our back-end that are tightly coupled with Onyx. Colloquially these systems are often referred to as “reliable updates” or just “Onyx updates”. I like to think of Onyx as a small copy of the back-end database, with just the data that a particular user needs and has access to.

In most cases, and in particular for pieces of data that originate in the back-end, persisting data and then reading it from disk makes sense for our use-cases. However, there are some pieces of data which are ephemeral - short-lived, and not representative of some permanent state. Some examples of this are:

  • Is your device offline?
  • Are we fetching some data from the back-end?

As a litmus test, if the answer to both of the following questions is yes, then the data is probably ephemeral:

  • If I kill the app and open it again, would this data still be accurate?
  • Does this data exist only on the client, or is it coming from the server?

We have a way to handle ephemeral data in Onyx - initWithStoredValues. This boolean parameter to useOnyx and Onyx.connectWithoutView defaults to true, but if it’s false, then the first time the data is requested it will not be read from cache or disk immediately, preventing the consumption of stale data stored in Onyx with the same key.

Regardless of whether consumers of a piece of Onyx data pass initWithStoredValues: false, all Onyx data is persisted to disk - that’s just the internal design of Onyx.

Problem

When developers forget (or don’t know) to pass initWithStoredValues: false to useOnyx invocations accessing an ephemeral piece of data, stale data is read from disk, which causes bugs (example).

Solution

Introduce the concept of RAM-only Onyx keys. The way this would work is that Onyx keys can be denoted with the ramonly_ prefix, and then Onyx will not ever write that data to disk, preventing it from ever being read from disk in a stale state. Then deprecate and remove initWithStoredValues from Onyx.

This solves the core problem in that ephemeral data can be configured once in Onyx.init, and all usages of that data will implicitly be treated as such. But it also has some tertiary advantages:

  • Simpler: You can’t read stale data from disk if you never write it to disk in the first place.
  • More efficient: When we write data to disk with the intention of never reading it from disk, that wastes time and computer resources.
Issue OwnerCurrent Issue Owner: @JKobrynski

Metadata

Metadata

Labels

Type

No type

Projects

Status

HIGH

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions