S
SolidJS4mo ago
Andre

Passing "up" signals in Solid

I am trying to understand how can you go by reading values from signals defined in children components in SolidJS. I exemplified my situation in the code bellow (with a solution that I came up with but don’t know if is ideal): I have one component that handles the content being edited (RecordEditor). The submission of the content written by the user is supposed to happens up in the hierarchy, in the AddRecordModal component. That means I need to “access the signals on the children component”.
function AddRecordModal(props: Props) {
const [title, setTitle] = createSignal<string>("");
const [amount, setAmount] = createSignal<number>();

createEffect(() => {
console.log(title(), amount());
});

return (
<div>
<RecordEditor class={styles.content} title={[title, setTitle]} amount={[amount, setAmount]} />
<button onClick={() => console.log(title(), amount())}>Submit record</button>
</div>
);
}

function RecordEditor(props: {
class?: string;
title: [Accessor<string>, Setter<string>];
amount: [Accessor<string | number | undefined>, Setter<number | undefined>];
}) {
const [title, setTitle] = props.title || createSignal<string>();
const [amount, setAmount] = props.amount || createSignal<number>();

return (
<div class={clsx(styles.container, props.class)}>
<input type="text" placeholder="Title" value={title()} onInput={(e) => setTitle(e.currentTarget.value)} />
<input
type="number"
placeholder="Amount"
value={amount()}
onInput={(e) => setAmount(parseFloat(e.currentTarget.value))}
/>
</div>
);
}
function AddRecordModal(props: Props) {
const [title, setTitle] = createSignal<string>("");
const [amount, setAmount] = createSignal<number>();

createEffect(() => {
console.log(title(), amount());
});

return (
<div>
<RecordEditor class={styles.content} title={[title, setTitle]} amount={[amount, setAmount]} />
<button onClick={() => console.log(title(), amount())}>Submit record</button>
</div>
);
}

function RecordEditor(props: {
class?: string;
title: [Accessor<string>, Setter<string>];
amount: [Accessor<string | number | undefined>, Setter<number | undefined>];
}) {
const [title, setTitle] = props.title || createSignal<string>();
const [amount, setAmount] = props.amount || createSignal<number>();

return (
<div class={clsx(styles.container, props.class)}>
<input type="text" placeholder="Title" value={title()} onInput={(e) => setTitle(e.currentTarget.value)} />
<input
type="number"
placeholder="Amount"
value={amount()}
onInput={(e) => setAmount(parseFloat(e.currentTarget.value))}
/>
</div>
);
}
5 Replies
Raqueebuddin Aziz
Either make the signal global, in a context or in the parent component
jer3m01
jer3m014mo ago
For small numbers of signals your approach is correct, more commonly we set 2 (or 3 with default) props per signal instead of an array. (If you want to use multiple props I'd recommend copying this utility, usage example) Otherwise for many signals a context is easier to manage: https://docs.solidjs.com/concepts/context.
Andre
Andre4mo ago
Ok! Thank you so much for the examples, that was what I was needing the most! I just didn't get what you meant by "more commonly we set 2 (or 3 with default) props per signal instead of an array." Since those two components are directly in contact, I think context would be too much in this case so I wanted to find if there a less complex route
jer3m01
jer3m014mo ago
Instead of title: [Accessor<string>, Setter<string>]; we set 2/3 props:
title: string;
defaultTitle: string;
onTitleChange: Setter<string>;
title: string;
defaultTitle: string;
onTitleChange: Setter<string>;
then used as:
const [title, setTitle] = createControllableSignal({
defaultValue: () => props.defaultTitle ?? "other default",
onChange: props.onTitleChange,
value: () => props.title,
});

title() // string
setTitle("updated title")
const [title, setTitle] = createControllableSignal({
defaultValue: () => props.defaultTitle ?? "other default",
onChange: props.onTitleChange,
value: () => props.title,
});

title() // string
setTitle("updated title")
parent component:
const [title, setTitle] = createSignal<string>("");
<RecordEditor title={title} onTitleChange={setTitle} />
// or
<RecordEditor defaultTitle="default title controlled entirely by subcomponent" />
const [title, setTitle] = createSignal<string>("");
<RecordEditor title={title} onTitleChange={setTitle} />
// or
<RecordEditor defaultTitle="default title controlled entirely by subcomponent" />
Andre
Andre4mo ago
Ohh, ok!! That makes sense, thanks for the example!!
Want results from more Discord servers?
Add your server
More Posts
useNavigate - navigate(path) throws "computations created outside a `createRoot`" and errorSometimes (not 100% of the time) when a user selects a new category in the UI, the following code se(node:53181) Warning: An error event has already been emitted on the socket.Has anyone ever encountered the problem: ```bash VITE v4.5.2 ready in 435 ms ➜ Local: httpCan't use an image without src/assets/ at the pathI have a problem why can't I use images from the assets folder if there is no src/assets/image.png asolid-router | return Navigate as componentIs there any way to return `<Navigate href="/auth/login" />` as a component rather than an element? Anchor with target="_blank" leading to app's URLI have a link with the `href` set to an external link for an image. When clicking on this link, a neSolid-start site shows blank page when deployed with github-pagesThis is the deploy.yml I used https://nitro.unjs.io/deploy/providers/github-pages repo https://githIs there a way to get Server Reference inside SolidStart? or other way to use webSocketsI just want to know if there is way to get to server reference that would be usable inside Socket.ioPassing data from `event.locals` to FrontendHey folks, I'm super new to solid/solid start, but I'm trying to implement some authentication and IHow does the "You might not need an effect" page from react.dev translate to SolidJS's effects?I feel like they are both the same construct, but since Solid has a fundamentally different way of rDoes solid-element support defining methods on web components?I'm not currently using `solid-element` to define my web component, because I need to define methods