GithubHelp home page GithubHelp logo

solid's Introduction

Nano Store Solid

Solid integration for Nano Stores, a tiny state manager with many atomic tree-shakable stores.

  • Small. Less than 1 KB with all helpers. Zero dependencies.
  • Fast. With small atomic and derived stores, you do not need to call the selector function for all components on every store change.
  • Tree Shakable. The chunk contains only stores used by components in the chunk.
  • Helpers. Designed to keep code clean and save a few keystrokes.
  • Was designed to move logic from components to stores.
  • It has good TypeScript support.

Quick start

Install it:

pnpm add nanostores @nanostores/solid # or npm or yarn

Use it:

// store.ts
import { action, atom, computed } from 'nanostores';

export const counter = atom(0);

export const increase = action(counter, 'increase', (store) => {
  counter.set(counter.get() + 1);
});

// Use computed stores to create chains of reactive computations.
export const doubled = computed(counter, current => current * 2);
import { useStore } from '@nanostores/solid';
import { counter, increase } from './store';

function Counter() {
  const count = useStore(counter);
  return <h1>{count()} around here ...</h1>;
}

function Controls() {
  return <button onClick={increase}>one up</button>;
}

Server-Side Rendering

Nano Stores support SSR. Use standard strategies.

import { isServer } from 'solid-js/web';

if (isServer) {
  settings.set(initialSettings);
  router.open(renderingPageURL);
}

You can wait for async operations (for instance, data loading via isomorphic fetch()) before rendering the page:

import { renderToString } from 'solid-js/web';
import { allTasks } from 'nanostores';

post.listen(() => {}); // Move store to active mode to start data loading
await allTasks();

const html = renderToString(<App />);

Usage with @nanostores/router

import { createRouter } from '@nanostores/router';
import { useStore } from '@nanostores/solid';
import { Match, Suspense, Switch, lazy } from 'solid-js';

export const routerStore = createRouter({
  home: '/',
  post: '/posts/:postId',
  comment: '/posts/:postId/comments/:commentId',
});

const Home = lazy(() => import('./pages/Home'));
const Post = lazy(() => import('./pages/Post'));
const Comment = lazy(() => import('./pages/Comment'));
const NotFound = lazy(() => import('./pages/NotFound'));

export function Router() {
  const page = useStore(routerStore);

  return (
    <Switch fallback={<NotFound />}>
      <Match when={page().route === 'home'}>
        <Home />
      </Match>
      <Match when={page().route === 'post'}>
        <Post postId={page().params.postId} />
      </Match>
      <Match when={page().route === 'comment'}>
        <Comment postId={page().params.postId} commentId={page().params.commentId} />
      </Match>
    </Switch>
  );
}

License

MIT

solid's People

Contributors

agustinmulet avatar ai avatar btakita avatar jlengstorf avatar keraf avatar knaplin avatar wobsoriano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

solid's Issues

Move to npm org

Do you want to move project to our npm org with name like @nanostores/solid?

If yes, give me your npm account name, I will add you to the org.

Rename GitHub repo

We moved React, Preact and Vue integrations to repos like nanostores/react, nanostores/preact, nanostores/vue.

Do you want to rename project to nanostores/solid to follow the name system?

`useStore()` Value Incorrectly Rendered in Astro SPA Mode

I'm using SolidJS for the first time; to get familiar with it I'm recreating a simple template project I originally did using Svelte components in Astro. In doing so I noticed some odd behavioral differences between mirrored Svelte and Solid components using the same Nanostores store.

My template project can be found here for reference: https://github.com/AustinFoss/astro-nanostores-example/tree/main

It's an Astro project using their SPA mode: https://docs.astro.build/en/guides/view-transitions/#full-site-view-transitions-spa-mode

At first the useStore function correctly updates the Solid component's DOM, and the Svelt counterpart's simultaneously. But when navigating away to the "About" page then back "Home" only the Svelte component initially displays the number where the counter left off while the Solid counter shows 0. However, when resuming to increment/decrement the counter Solid jumps directly back to where it left off.

I'm not exactly sure how to prompt the Solid component to remember it's old value before the page transition, nor am I exactly sure this is a problem with @nanostores/solid or astro:transitions. This is most likely a problem with my understanding of how Solid does it's rendering but if anyone can help shed some light on this and offer some insight that would be much appreciated.

output

Should there be a version of useStore & useSignal which return a [accessor, setter] pair?

A [accessor, setter] pair would be useful for situations where solid components use both the accessor & setter. The atom.set() function could be setter but returning the [accessor, setter] pair is more idiomatic to Solidjs.

If we were to go this route, I propose the following types:

import type { Store } from 'solid-js/store'
import type { ReadableAtom, WritableAtom } from 'nanostores'
declare function useSignal<Value>(atom: WritableAtom<Value>):[()=>Value, (val:Value)=>void];
declare function useStore<Value>(atom: WritableAtom<Value>):[Store<Value>, (val:Value)=>void];
declare function useMemo<Value>(atom: ReadableAtom<Value>):()=>Value

Creating Computed Stores with Arguments

Issue

The scenario I am running into is that I have a computed that looks as follows:

 computed(tableStore, (tables) => {
            return tables.filter(table => table.status === TableStatuses.ACTIVE && table.userId === userId());
        })

Now The above expects a userId(). However this is a somewhat dynamic value so I created a function in my store that looks as follows:

export const getActiveTablesByUser = <T>(userId: Accessor<T>) => {
    const store = createStore(
        computed(tableStore, (tables) => {
            return tables.filter(table => table.status === TableStatuses.ACTIVE && table.userId === userId());
        })
    );
    return store();
}

I then reference this function inside of a component:

const activeTables = () => getActiveTablesByUser(userId);

Then I can call activeTables() to get the active tables via a computed.

My issue and question is I had to work around Solid in order to get it to not complain about it possibly breaking reactivity so the only way I could find in order to do so was the above.

Is this the expected approach or should I be doing something different to allow for computed to use that userId() value?

useStore build error: Argument of type 'WritableAtom<number>' is not assignable to parameter of type 'Store<any>'.

Hello! I have this unique case where this lines of code:

import { useStore } from "@nanostores/solid";
import { atom } from "nanostores";

const store = atom(1);
useStore(store);

Will produce an error (both in VS Code and in build): Argument of type 'WritableAtom<number>' is not assignable to parameter of type 'Store<any>'.. Reference action: https://github.com/imballinst/test-nanostores-solid/actions/runs/2855290395.

But, if I changed the useStore using the raw ones from https://github.com/nanostores/solid/blob/master/src/index.ts (as shown in this commit), then the build will pass through. Reference action: https://github.com/imballinst/test-nanostores-solid/runs/7825571407.

I take it this might be an issue from the transpilation? Because it works fine using the raw .ts source but not OK with the .d.ts from the bundled thing. I'm happy to submit a PR for this fix. Thanks!

Pre-rendered content does not re-render to show updated content from storage engines in SSR environments

Describe the bug

In SSR environments such as Astro + Solid, pre-rendered content does not re-render to show updated content from persistent storage engines.

I understand that this package only claims to be an integration for Nano Stores and not Nano Stores Persistent but I will still open this issue just in case.

Your Example Website or App

Minimal reproduction

Steps to Reproduce the Bug or Issue

  1. Open Minimal reproduction
  2. Observe that initial rendered value is initialValue
  3. Click on button and observe that rendered value changes.
  4. Observe also that localStorage value changes as well.
  5. Refresh tab and observe that rendered value is back to initialValue and does not update to show correct value from localStorage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.