Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hope to provide Keepalive component #2376

Open
yibird opened this issue Dec 6, 2024 · 2 comments
Open

Hope to provide Keepalive component #2376

yibird opened this issue Dec 6, 2024 · 2 comments
Milestone

Comments

@yibird
Copy link

yibird commented Dec 6, 2024

Describe the bug

Hope to provide Keepalive component

Your Example Website or App

Hope to provide Keepalive component

Steps to Reproduce the Bug or Issue

Hope to provide Keepalive component

Expected behavior

Hope to provide Keepalive component

Screenshots or Videos

Hope to provide Keepalive component

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • Browser: [e.g. Chrome, Safari, Firefox]
  • Version: [e.g. 91.1]
    Hope to provide Keepalive component

Additional context

Hope to provide Keepalive component

@ahzvenol
Copy link

ahzvenol commented Dec 7, 2024

I've been waiting for this feature for two years.
You can check it out here: solid-router issue #204.

Currently, I'm using solid-keep-alive as an alternative.

@ryansolid ryansolid added this to the 2.0.0 milestone Jan 8, 2025
@hex0xf
Copy link

hex0xf commented Jan 15, 2025

Yes, in fact, you may not need an API like vue. This is a keep-alive function I implemented. It works well and meets all scenarios. Toggle is a substitute for Show.

export default function createKeepAlive() {
  const owner = getOwner();
  let cache:
    | {
        depose(): void;
        el: JSX.Element;
      }
    | undefined = undefined;
  function render(
    el: () => JSX.Element,
    active: Accessor<boolean> = () => true
  ) {
    if (!cache) {
      cache = createRoot((depose) => {
        return {
          el: <ActiveProvider value={active()} children={el()} />,
          depose,
        };
      }, owner);
    }
    return cache.el;
  }
  onCleanup(() => {
    cache && cache.depose();
  });

  return render;
}


export function Toggle<T>(props: ToggleProps<T>) {
  let render: RenderType = (el) => el();
  let renderFallback = render;
  if (props.keepAlive !== false) {
    render = createKeepAlive();
    renderFallback = createKeepAlive();
  }
  const when = createMemo(() => Boolean(props.when));

  return (
    <Show
      when={when()}
      fallback={renderFallback(
        () => props.fallback,
        () => !when()
      )}
    >
      {render(
        () => props.children,
        () => when()
      )}
    </Show>
  );
}

export interface ToggleProps<T> {
  when: T | undefined | null | false;
  fallback?: JSX.Element;
  children: JSX.Element;
  keepAlive?: boolean;
}

type RenderType = (
  el: () => JSX.Element,
  active: Accessor<boolean>
) => JSX.Element;

You can also use object pool technology to cache loops, but these two are different concepts. Although vue is simple, it is actually very confusing.
Each is a substitute for For.

import { createRootPool } from '@solid-primitives/rootless';
import { For, JSX } from 'solid-js';
import { useActiveMemo } from './Active';


export default function Each<T extends readonly any[]>(props: {
  each: T | undefined | null | false;
  fallback?: JSX.Element;
  component: (props: { data: T[number]; active?: boolean }) => JSX.Element;
  limit?: number;
}) {
  const activeEach = useActiveMemo(() => props.each);
  const pool = createRootPool<T[number], JSX.Element>(
    (it, active) => {
      const el = props.component({
        get data() {
          return it();
        },
        get active() {
          return active();
        },
      });
      return el;
    },
    { limit: props.limit || 100 }
  );

  return (
    <For each={activeEach()} fallback={props.fallback}>
      {(it) => pool(it)}
    </For>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants