The props are reactive, right?

I've created a small wrapper around solid-table:
export function DataTable<TData extends { id: string }>(props: {
data: TableOptions<TData>["data"];
columns: TableOptions<TData>["columns"];
}) {
// const [data, setData] = createSignal(props.data);
const table = createSolidTable({
data: props.data,
// data: data(),
columns: props.columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});

createEffect(() => console.log(props.data));

// createEffect(() => setData(props.data));
// createEffect(() => console.log(data()));
export function DataTable<TData extends { id: string }>(props: {
data: TableOptions<TData>["data"];
columns: TableOptions<TData>["columns"];
}) {
// const [data, setData] = createSignal(props.data);
const table = createSolidTable({
data: props.data,
// data: data(),
columns: props.columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});

createEffect(() => console.log(props.data));

// createEffect(() => setData(props.data));
// createEffect(() => console.log(data()));
I use this component within a Suspense. Therefore props.data is equal to [], then populated with data. However, it doesn't seem to trigger an update. I tried to use a signal in the middle to make it reactive (see the comments) even if props.data is already reactive. The effects are triggered and logging the data, but the table remains empty 🤔
10 Replies
Brendonovich
Brendonovich8mo ago
props are reactive, but you're reading them once in the component body and then that's it. you'll want to do something like this instead
export function DataTable<TData extends { id: string }>(props: {
data: TableOptions<TData>["data"];
columns: TableOptions<TData>["columns"];
}) {
// const [data, setData] = createSignal(props.data);
const table = createSolidTable({
get data() {
return props.data
},
get columns() {
return props.columns
},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});
export function DataTable<TData extends { id: string }>(props: {
data: TableOptions<TData>["data"];
columns: TableOptions<TData>["columns"];
}) {
// const [data, setData] = createSignal(props.data);
const table = createSolidTable({
get data() {
return props.data
},
get columns() {
return props.columns
},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});
binajmen
binajmenOP8mo ago
Ow, works like a charm. What should I read to better understand this paradigm? I feel I missed a step in my understanding of theses cases in the Solid world Is it common to use this "trick"?
Brendonovich
Brendonovich8mo ago
not sure where else to read about it, but yeah it's pretty common props are (usually) getters and components only run once so reactivity needs to be triggered through function calls or accessing getters
binajmen
binajmenOP8mo ago
I'll definitely keep that in mind thank you 🙏
bigmistqke
bigmistqke8mo ago
imo this video is great to get an intuition behind the why https://www.youtube.com/watch?v=cELFZQAMdhQ
SolidJS
YouTube
Intro to SolidJS reactivity (in 5 minutes)
An introduction video that walks you through Solid's reactivity in under 5 minutes.
Birk Skyum
Birk Skyum8mo ago
The guides in docs.solidjs.com are a good intro as well
binajmen
binajmenOP8mo ago
Yeah I thought I understood all the finesse of Solid while observing and not using. Now that I'm using it actively. I guess I was wrong 😅 I went through the video and this guide: https://docs.solidjs.com/advanced-concepts/fine-grained-reactivity Still, it is unclear for me how the getter trick is working in my case how passing the data via a getter function make it reactive?
data: props.data,

vs.

get data() {
return props.data
},
data: props.data,

vs.

get data() {
return props.data
},
does the getter function magically subscribe itself to the signal behing props.data?
bigmistqke
bigmistqke8mo ago
Props is an object that has getters for its dynamic properties:
<Component prop={signal()}/>
<Component prop={signal()}/>
becomes after transpilation something like
Component({ get prop(){ return signal() } })
Component({ get prop(){ return signal() } })
When inside Component you access the prop it will call this signal.
const value = props.prop
const value = props.prop
you can think of as
const value = signal()
const value = signal()
If you access a signal outside of an effect it will not be reactive (because there is no effect to be re-run) That's why
const table = createSolidTable({
data: props.data,
columns: props.columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});
const table = createSolidTable({
data: props.data,
columns: props.columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getRowId: (row) => row.id,
});
is not reactive as all the signals hidden behind the props are called during initialisation. While with
const table = createSolidTable({
get data() {
return props.data
},
get columns() {
return props.columns
},
...
});
const table = createSolidTable({
get data() {
return props.data
},
get columns() {
return props.columns
},
...
});
we are not accessing/calling the signals during initialisation, but instead passing them straight to createSolidTable.
bigmistqke
bigmistqke8mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
binajmen
binajmenOP8mo ago
thank you, very clear
Want results from more Discord servers?
Add your server