question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] Best practices for large objects?

See original GitHub issue

Hi all,

So far we are loving jotai. Amazing work ❤️.

I’d like to start a conversation around best practices for larger objects. Let’s say our back-end gives us a fairly large object which would be mutable at different levels of the object.

const cars = [
    {
        make: 'Audi',
        model: 'RS6',
        price: {
            value: 999.50,
            currency: 'USD'
        },
        parts: [
            {
                type: 'engine',
                power: 'lot-of hp',
                price: { ... },
                factoryLocations: [
                    { country: 'China', stock: 150 },
                    { country: 'Germany', stock: 0 },
                ]
            }, // ... n more
        ]
    },
    // ... n more
]

Now our React component tree has <Car /> with a list of <Parts />, which has a list of <Factory />s.

What would be the recommended way to go about

  • Adding / removing parts
  • Adding / updating factory locations
  • Updating price

Using jotai? I am personally very familiar with MobX, where this would be one large observable object (or class instance). However, I am not sure how to look at this in atoms.

Would each car be an atom, with parts turned into atoms and factory locations into atoms? Any other approaches?

I’d love to hear thoughts on this! 😊

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:7
  • Comments:15 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
dai-shicommented, Feb 20, 2021

So, there are mainly three approaches.

  1. a big atom to put an object as a whole and create smaller derived atoms
  2. create a map of (id, item), normalized data structure
  3. create small atoms and combine them with atom references

a big atom

This idea is not very atomic, but it works. This is useful if we need to persist data or push back to the server.

const dataAtom = atom({
  people: [
    { name: 'Luke Skywalker', height: '172' },
    { name: 'C-3PO', height: '167' },
  ],
  films: [
    { title: 'A New Hope', episode_id: 4, planets: [{ name: 'Tatooine' }, { name: 'Alderaan' }] },
    { title: 'The Empire Strikes Back', episode_id: 5, planets: [{ name: 'Hoth' }] },
  ],
}

const peopleAtom = atom(get => get(dataAtom).people)
const filmsAtom = atom(get => get(dataAtom).films)

const createFilmAtom = index => atom(get => get(filmsAtom)[index])

(Wait a minute, I might notice a missing optimization in the current implementation…)

There are utility functions to ease this pattern: selectAtom, splitAtom, focusAtom

normalized data

Like you implied normalizr.

const peopleMapAtom = atom({
  p1: { name: 'Luke Skywalker', height: '172' },
  p2: { name: 'C-3PO', height: '167' },
})

const planetsMapAtom = atom({
  a1: { name: 'Tatooine' },
  a2: { name: 'Alderaan' },
  a3: { name: 'Hoth' },
})

const filmsMapAtom = atom({
  f1: { title: 'A New Hope', episode_id: 4, planets: ['a1', 'a2'] },
  f2: { title: 'The Empire Strikes Back', episode_id: 5, planets: ['a3'] },
})

There are utility functions to ease this pattern: atomFamily

atom references

This looks crazy, but it works.

const dataAtom = atom({
  people: atom([
    atom({ name: 'Luke Skywalker', height: '172' }),
    atom({ name: 'C-3PO', height: '167' }),
  ]),
  films: atom([
    atom({ title: 'A New Hope', episode_id: 4, planets: [atom({ name: 'Tatooine' }), atom({ name: 'Alderaan' })] }),
    atom({ title: 'The Empire Strikes Back', episode_id: 5, planets: [atom({ name: 'Hoth' })] }),
  ],
}

This is pseudo code. We don’t manually create like this. It’s up to you at which level you top making atoms. For example, we don’t need to wrap with atoms for planets.

To support this pattern, atom returns a unique string, so you can specify it to key={}.


I would personally would like to recommend the third pattern. It’s pretty much like jotai, the power of it. Having nested atoms is tricky, though. I wonder how DX would be like. TS is almost necessary for this.

The first pattern would be good for persistence or server cache. The second one might be easier to understand, especially with atomFamily.

1reaction
dai-shicommented, Feb 21, 2021

Neither focusAtom nor selectAtom doesn’t have caching mechanism. If that’s ok, this should work?

const interactiveItemsAtom = atom(
  (get) => get(itemsAtom).filter((itemAtom) => get(atom((get) => get(itemAtom).interactive)))
)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Java passing large objects best practices - Stack Overflow
As I try to split up these large methods, I find myself constantly needing to pass the large case object by reference to...
Read more >
Proper practice on handling a large number of objects in ...
My question is, what if I had 1000 students, each with a FName, SName, Address etc. Would I continue on and create 1000...
Read more >
Ranking Questions: Dos and Don'ts in 2021 - Qualtrics
Don't create long lists of items for people to rank. Researchers often want to ask respondents to rank huge lists to see what...
Read more >
In-depth Interview Questions on Salesforce Objects and ...
You can create only 100 big objects per org. The limits for big object fields are similar to the limits on custom objects,...
Read more >
To BLOB or Not To BLOB: Large Object Storage in a Database ...
As expected from the common wisdom, objects smaller than 256K are best stored in a database while objects larger than 1M are best...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found