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.

Good pattern for updating atoms based on subscription

See original GitHub issue

Lets say I have an API that I can subscribe to, and any time a value changes (can happen once a frame at 60FPS) I would want to update an atom to always reflect that

Currently I can just create a useEffect to do this at the App.tsx level, but wondering if there’s an atoms-only way to do this.

some pseudocode:

useEffect(() => {
  async function load() {
    setAtom(client.get(someId))
  }
  client.subscribe(someId, (msg) => setAtom(msg));
  () => {
    client.unsubscribe(someId);
  }
}, [])

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:23 (18 by maintainers)

github_iconTop GitHub Comments

1reaction
dai-shicommented, Dec 5, 2021

atomWithObservable with initial value to avoid suspense? That’s possible. We did something like that in atomWithQuery in jotai/query. Would you like to open a new issue for tracking?

For people who don’t want to use experimental Suspense yet?

For this specific purpose, we have loadable.

1reaction
dai-shicommented, Dec 20, 2020

Let me try ideating something.

So, what works now is something like this:

const dataAtom = atom(null)

const useDataAtomWithEffect = () => {
  const [data, setData] = useAtom(dataAtom)
  useEffect(() => {
    const init = async () => {
      setData(await fetchData())
    }
    const unsubscribe = subscribeToData(setData)
    init()
    return unsubscribe
  }, [setData])
  return data
}

Let’s see if we can generalize a bit.

// define an atom
const dataAtom = atom(null)
// define an atom initializer
const initializeDataAtom = async (set) => {
  const unsubscribe = subscribeToData(set)
  (async () => { set(await fetchData()) })()
  return unsubscribe
}

// list all atoms with initializer
const atomsWithInitializer = [
  [dataAtom, initializeDataAtom]
]

// internal component
const InitializeAtom = ({ atom, initialize }) => {
  const [value, setValue] = useAtom(atom)
  useEffect(() => {
    return initialize(setValue)
  }, [setValue])
  return null
}

// component to initialize atoms recursively
const InitializeAtoms = ({ atoms, children }) =>
  atoms.reduceRight(a, [atom, initialize] =>
    React.createElement(InitializeAtom, { atom, initialize }, a),
    children,
  )

// How to use
const App = () => (
  <Provider>
    <InitializeAtoms atoms={atomsWithInitializer}>
      <MainLayout />
    </InitializeAtoms>
  </Provider>
)

Just a rough idea.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Make And Maintain Atomic Design Systems With ...
This article provides a detailed guide to building and maintaining atomic design systems with Pattern Lab 2. The benefits of UI design systems ......
Read more >
How to organize your components using the Atomic Design
First of all we have to create our folder structure in which store our components. So, let's create a src directory which will...
Read more >
Publisher Subscriber (Pub-Sub) Design Pattern
The publish subscribe pattern, sometimes known as pub sub pattern, is an architectural design pattern that enables publishers and subscribers to communicate ...
Read more >
Jotai: The Ultimate React State Management - 100ms
Jotai, the atom-based state management for React. But what is Jotai, ... Jotai is based on the new Recoil pattern and library by...
Read more >
An Introduction to Atomic Design and Pattern Lab in SiteFarm
complete: pattern is ready to be moved to production. a green dot. Pattern State Example. This is great when developing for a client...
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