tozz
tozz
Explore posts from servers
SSolidJS
Created by tozz on 12/18/2023 in #support
Solid Router 0.10.x double render of App
Just upgraded to 0.10.5 and the migration of code was simple enough, but running into a weird scenario where if I have a wrapper element in my <App> it gets rendered twice, whereas if I just have <>...</> it renders fine. This causes double rendering (two 'standard-grid' divs, two menus etc).
const App = (props: { children?: JSXElement}) => (
<div class="standard-grid">
<Menu />
{props.children}
</div>
);
const App = (props: { children?: JSXElement}) => (
<div class="standard-grid">
<Menu />
{props.children}
</div>
);
This works (but adding the div inside the <> causes it to render double again.
const App = (props: { children?: JSXElement}) => (
<>
<Menu />
{props.children}
<>
);
const App = (props: { children?: JSXElement}) => (
<>
<Menu />
{props.children}
<>
);
Router is setup very simply with <Router root={App}>...
Edit: I had missed a previous wrapped route that caused the double render, nothing to see here 😅
1 replies
SSolidJS
Created by tozz on 9/23/2023 in #support
Best way of passing props from Provider to Context
So I'm making a simple context with a Provider "wrapper" as is quite common to wrap functionality. I pass some values to it in JSX that should then be available when using the context.
interface DataGridContextValue {
readonly markets: Record<string, string>;
}

interface DataGridProviderProps {
children: JSX.Element;
markets: Record<string, string>;
}

export const DataGridContext = createContext<DataGridContextValue>();

export const DataGridProvider: Component<DataGridProviderProps> = (props) => {
// Implementation ...

const values = {
get markets() {
return props.markets;
},
// ... implementation API.
};

return <DataGridContext.Provider value={values}>{props.children}</DataGridContext.Provider>;
};
interface DataGridContextValue {
readonly markets: Record<string, string>;
}

interface DataGridProviderProps {
children: JSX.Element;
markets: Record<string, string>;
}

export const DataGridContext = createContext<DataGridContextValue>();

export const DataGridProvider: Component<DataGridProviderProps> = (props) => {
// Implementation ...

const values = {
get markets() {
return props.markets;
},
// ... implementation API.
};

return <DataGridContext.Provider value={values}>{props.children}</DataGridContext.Provider>;
};
This works well, but curious as to if there's a smarter way that I'm missing. Solid isn't wrapping reactivity for the value attribute, so I need to do something to keep reactivity. For usage of the provider it looks like this:
export const DataGrid: Component<DataGridProps> = () => {
const [markets] = createResource<Record<string, string>>(getMarkets);

return (
<DataGridProvider markets={markets()}>
...children
</DataGridProvider>
);
};
export const DataGrid: Component<DataGridProps> = () => {
const [markets] = createResource<Record<string, string>>(getMarkets);

return (
<DataGridProvider markets={markets()}>
...children
</DataGridProvider>
);
};
6 replies
SSolidJS
Created by tozz on 8/6/2023 in #support
Reactivity inside closure in return value
I have a function with a store, singals etc. This function returns an object, that object contains a function that is to be used as an event in the caller context. const { onSubmit } = someFunction() The definition of onSubmit inside someFunction
const onSubmit = (callback: (e: SubmitEvent) => void) => (event: SubmitEvent) => {
event.preventDefault();

// nodes are a store
Object.keys(nodes).forEach((key) => nodes[key].validate());

callback(event);
};
const onSubmit = (callback: (e: SubmitEvent) => void) => (event: SubmitEvent) => {
event.preventDefault();

// nodes are a store
Object.keys(nodes).forEach((key) => nodes[key].validate());

callback(event);
};
So the way you use it is <form onSubmit={onSubmit(() => { // my callback })} ...> This causes a lint error This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored. on the returning inner function. Likely very simple to fix, if I didn't need the closure for callback I could just store the inner function with createMemo, but I need the closure
5 replies
SSolidJS
Created by tozz on 7/25/2023 in #support
Reaching into nested properties and keeping them reactive?
Coming from React I really like that I can destruct nested props into single variables, in this example I have a JSON (using createResource with flow as the signal) that has a couple of levels where I parse it and loop it over with a <For> <For each={flow().ui.nodes}>{nodeValue}</For> The nodeValue function looks like this (I could of course inline it all, and I might, but for now it's its own function)
const nodeValue = (node) => {
return (
<Switch>
<Match when={node.attributes?.node_type === 'input'}>
<>
{node.type === 'hidden' && (
<input type="hidden" name={node.attributes.name} value={node.attributes.value} />
)}
{node.type === 'text' && (
<Input name={node.attributes.name} value={node.attributes.value} label={node.attributes.label} />
)}
</>
</Match>
</Switch>
);
};
const nodeValue = (node) => {
return (
<Switch>
<Match when={node.attributes?.node_type === 'input'}>
<>
{node.type === 'hidden' && (
<input type="hidden" name={node.attributes.name} value={node.attributes.value} />
)}
{node.type === 'text' && (
<Input name={node.attributes.name} value={node.attributes.value} label={node.attributes.label} />
)}
</>
</Match>
</Switch>
);
};
Can I avoid having to do node.attributes.x and rather get node.attributes as a flat var and use var.name instead?
3 replies