How to export setter function for component?

Hi, I'm relatively new to Solid world and whole frontend, I used to work in Java style codebases. I have legacy code, which I'm trying to replace with Solidjs components. Lets presume I have timer component which has time set in creation via prop. Now I need to change time, which is signal created inside component. How to tell component to update its time? Currently am doing this was, but it feels stupid and complicated. Thank you. export type CountDownPanelProps = { template: string; defaultTimestamp: Date; updateInterval: number; classRules: { [k: string]: (timeLeftMs: number) => boolean }; registerUpdateTimestampHandler?: ( handler: (newTimestamp: Date) => void ) => void; registerUpdateTemplateHandler?: ( handler: (newTemplate: string) => void ) => void; }; In component: if (props.registerUpdateTimestampHandler) { props.registerUpdateTimestampHandler((newTimestamp) => { initialTimeStamp = newTimestamp.getTime(); updateTimer(); }); } if (props.registerUpdateTemplateHandler) { props.registerUpdateTemplateHandler((newTemplate) => { template = newTemplate; updateTimer(); }); } Outside of component in legacy code: const timerComponent = CountDownPanel({ template: deliveryStatusTitle, defaultTimestamp: order.Delivery.getExpectedPickUp(), updateInterval: 1000, registerUpdateTimestampHandler: (handler) => { updateTimestamp = handler; }, registerChangeTemplateHandler: (handler) => { updateTemplate = handler; }, }); Now I'm finally able to update component state in legacy code: updateTimestamp(newValue) updateTemplate(newTemplate) It's crazy complicated, but it works. Is there an easier way?
4 Replies
bigmistqke
bigmistqke6mo ago
quick tip: you can use markup in discord, p.ex you can get syntax highlighting with ```tsx
bigmistqke
bigmistqke6mo ago
minimal reproductions in https://playground.solidjs.com/ are also really welcome
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
bigmistqke
bigmistqke6mo ago
I would probably have timestamp as a reactive value, and maybe expose the timer's api with a ref-prop or have an enabled-prop maybe. something like
const [timestamp, setTimestamp] = createSignal()
// or use a signal if you don't like to cast
let api: { start: () => void, ... } = null!
createEffect(() => {
// some logic
if(props.enabled){
api.start()
}
})

return <Timer ref={api} timestamp={timestamp()} />
const [timestamp, setTimestamp] = createSignal()
// or use a signal if you don't like to cast
let api: { start: () => void, ... } = null!
createEffect(() => {
// some logic
if(props.enabled){
api.start()
}
})

return <Timer ref={api} timestamp={timestamp()} />
or
const [timestamp, setTimestamp] = createSignal()
return <Timer enabled={props.enabled} timestamp={timestamp()} />
const [timestamp, setTimestamp] = createSignal()
return <Timer enabled={props.enabled} timestamp={timestamp()} />
glassy
glassy6mo ago
Yes, the suggestion above (the last one) is probably how you should do it. It is the most simple/least code and most straightforward. In this new(er) world, you should try to push down as much as you can through props to the children components. If you want to change the timer's time, then just change the value of the time prop that you are passing to it. You may need to explain how the code in the parent component works if that doesn't seem like it would work for you.
Want results from more Discord servers?
Add your server