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

docs: explain better the distinction between islands and components #2369

Closed
skybrian opened this issue Mar 20, 2024 · 5 comments · Fixed by #2416
Closed

docs: explain better the distinction between islands and components #2369

skybrian opened this issue Mar 20, 2024 · 5 comments · Fixed by #2416
Labels

Comments

@skybrian
Copy link

Quoting @CAYdenberg in: #2363 (comment)

Well, if it helps, components that are children of islands can receive functions as props. So, your ComplexOrBigComponent could live in components/, receive onClick when used as a descendent of an island, and not receive it when used outside of an island. Just mark onClick as being optional in your props interface declaration (and handle the cases where it is undefined).

I also found this confusing at first. When should a file go under components/ versus islands/?

I had thought that islands were client-side and components were server-side, but that's not right. Instead, everything should be a component, except when it needs to be the root of a client-side hierarchy, and then it's an island. (Why? Because there are restrictions on what you can pass in to an island.)

In particular, the component page has some components tagged as islands that are really just components that can run on both client and the server. (A button could be an island, but why?)

@fro-profesional
Copy link

I don think is confusing, from the docs: https://fresh.deno.dev/docs/concepts/islands

Islands enable client side interactivity in Fresh. Islands are isolated Preact components that are rendered on the server and then hydrated on the client. This is different from all other components in Fresh, as they are usually rendered on the server only.

You mentioned

In particular, the component page has some components tagged as islands that are really just components that can run on both client and the server.

Thats what islands are, thats what the docs says "components that are rendered on the server and then hydrated on the client."

And for

(A button could be an island, but why?)

Why would not? buttons can be used to trigger forms by using props, or actions by onClick event, for the second will always be necessary to be an island or be used inside and island

@CAYdenberg
Copy link
Contributor

CAYdenberg commented Mar 22, 2024

I think based on the fact that multiple people are confused (who presumably took the time to try to understand, since they took the time to give feedback), that by definition it is confusing.

I think the concept that needs to be fleshed out is that the children of islands are still "within" the island. Or, put differently, a distinction should be made between the island "entry-point" and the components which are part of the island.

However, I am not a maintainer, so I won't make the call myself. It's also possible the change should be folded into the broader re-org of the Getting Started section (#1632 )

@fro-profesional
Copy link

I think based on the fact that multiple people are confused (who presumably took the time to try to understand, since they took the time to give feedback), that by definition it is confusing.

I guess u are right 🤔

@marvinhagemeister
Copy link
Collaborator

marvinhagemeister commented Mar 25, 2024

Component

A function that starts with an uppercase letter that can use hooks and optionally return JSX. Doesn't say anything about where it runs.

Island

A form of component that is bundled and executed it in the browser, looks the exact same as a normal component. The only difference is that they're put in special files like islands/MyIsland.tsx and Fresh flags components exported from these as an island.

Server Component

A form of component that's only run on the server. Looks the exact same as a normal component, only difference is where it's used. For Fresh means that if you only ever use this component in a route, then it will only run on the server.

@kiphud
Copy link
Contributor

kiphud commented Apr 26, 2024

Just as an anecdote, I did find this somewhat confusing at first, especially because I copied the Button island into a component in my Fresh project, and then was confused why it was constantly disabled. Of course, now this makes sense to me.

But then when I look at the interactive islands documentation now, looking at the following example:

islands/my-island.tsx
import { useSignal } from "@preact/signals";

export default function MyIsland() {
  const count = useSignal(0);

  return (
    <div>
      Counter is at {count}.{" "}
      <button onClick={() => (count.value += 1)}>+</button>
    </div>
  );
}

It's now clear to me that the button here, could be a components/Button and still function perfectly fine. I wonder if in a documentation level it's worth just creating an example which illustrates this use case a little more? Something like:

islands/my-island.tsx
import { useSignal } from "@preact/signals";
import Button from '../components/Button.tsx'

export default function MyIsland() {
  const count = useSignal(0);

  return (
    <div>
      Counter is at {count}.{" "}
      <Button onClick={() => (count.value += 1)}>+</Button>
    </div>
  );
}

marvinhagemeister pushed a commit that referenced this issue Apr 30, 2024
After reading the discussion at #2369, this PR introduces a small
addition to the docs which highlights how you can use server components
within islands.

This, coupled with the existing docs, should hopefully give people
enough of an example to understand that islands provide the
interactivity layer, and that server components within them can be
hydrated and made interactive too.

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

Successfully merging a pull request may close this issue.

5 participants