Question: nextjs13 server components

Author: droganovCreated Jul 11, 2023Updated Aug 18, 2024

I checked if I can use nanostroes with server components in Nextjs, and didn't find any luck. The below setup renders, but the store init does not fire, and I find store with the initial state both on on server and client.

Did anyone manage to use nanostores with Nextjs server components?

counterStore.ts

typescript
import { useStore } from '@nanostores/react'
import { atom, onMount, task } from 'nanostores'

const store = atom(0)

export const increment: VoidFunction = () => {
  store.set(store.get() + 1)
}

export const decrement: VoidFunction = () => {
  store.set(store.get() - 1)
}

export const initCounter = store.listen(() => {})

export const useCounter = (): number => useStore(store)

onMount(store, () => {
  console.log('onMount: ')
  task(async () => {
    const next = await Promise.resolve(10)
    console.log('next: ', next)
    store.set(next)
  })
})

page.tsx

typescript
import { allTasks } from 'nanostores'

import { Counter } from './Counter'
import { initCounter } from './counterStore'

const NanoPage = async (): Promise<JSX.Element> => {
  initCounter()
  await allTasks()
  return <Counter />
}

export default NanoPage

Counter.tsx

typescript
'use client'
import type { FunctionComponent } from 'react'

import { decrement, increment, useCounter } from './counterStore'

export const Counter: FunctionComponent = () => {
  const count = useCounter()
  console.log('count: ', count)
  return (
    <>
      page {count}
      <hr />
      <button className="yobta-button inline-flex" onClick={decrement}>
        -
      </button>
      <button className="yobta-button inline-flex" onClick={increment}>
        +
      </button>
    </>
  )
}