S
SolidJS6mo ago
Mtlive

how using createRoot?

I am developing a multi-language configuration for my program. I have implemented it in the following way so that it can be called inside the component or in some modules. (If I use context, I can't use it outside the component) However, I get such a warning in the browser console and I'm not sure if such a warning has any positive negative effect. "menus.tsx:10 computations created outside a createRoot or render will never be disposed" Please teach me, thank you!
import { createSignal, createRoot, createMemo } from 'solid-js'
import { en } from '~/i18n/en'
import { zh } from '~/i18n/zh'
import { vn } from '~/i18n/vn'
import * as i18n from '@solid-primitives/i18n'

export type Locale = 'en' | 'zh' | 'vn'

export type I18nDictionaries = {
en: typeof en
zh: typeof zh
vn: typeof vn
}

export interface LocaleOption {
label: string
value: Locale
disabled?: boolean
}

const dictionaries: I18nDictionaries = {
zh: zh,
en: en,
vn: vn
}

const localeOptions: LocaleOption[] = [
{ label: 'English', value: 'en' },
{ label: '简体中文', value: 'zh' },
{ label: 'Tiếng Việt', value: 'vn' }
]

let t: i18n.ChainedTranslator<I18nDictionaries[Locale], string>

const i18nStore = createRoot(() => {
console.log('i18n init.')
const [locale, setLocale] = createSignal<Locale>('en')

const dict = createMemo(() => i18n.flatten(dictionaries[locale()]))

const translator = i18n.translator(() => dict(), i18n.resolveTemplate)

t = i18n.chainedTranslator<I18nDictionaries[Locale], string>(
dict(),
translator
)

return { locale, setLocale }
})

export const useLocale = () => {
return {
t,
locale: i18nStore.locale,
setLocale: i18nStore.setLocale,
localeOptions
}
}
import { createSignal, createRoot, createMemo } from 'solid-js'
import { en } from '~/i18n/en'
import { zh } from '~/i18n/zh'
import { vn } from '~/i18n/vn'
import * as i18n from '@solid-primitives/i18n'

export type Locale = 'en' | 'zh' | 'vn'

export type I18nDictionaries = {
en: typeof en
zh: typeof zh
vn: typeof vn
}

export interface LocaleOption {
label: string
value: Locale
disabled?: boolean
}

const dictionaries: I18nDictionaries = {
zh: zh,
en: en,
vn: vn
}

const localeOptions: LocaleOption[] = [
{ label: 'English', value: 'en' },
{ label: '简体中文', value: 'zh' },
{ label: 'Tiếng Việt', value: 'vn' }
]

let t: i18n.ChainedTranslator<I18nDictionaries[Locale], string>

const i18nStore = createRoot(() => {
console.log('i18n init.')
const [locale, setLocale] = createSignal<Locale>('en')

const dict = createMemo(() => i18n.flatten(dictionaries[locale()]))

const translator = i18n.translator(() => dict(), i18n.resolveTemplate)

t = i18n.chainedTranslator<I18nDictionaries[Locale], string>(
dict(),
translator
)

return { locale, setLocale }
})

export const useLocale = () => {
return {
t,
locale: i18nStore.locale,
setLocale: i18nStore.setLocale,
localeOptions
}
}
3 Replies
bigmistqke
bigmistqke6mo ago
if u do not use ssr and u don't want to dispose those memos/effects/stores you can safely ignore those warnings. when an effect/signal is declared inside an effect solidjs can dispose them whenever the effect is ran again, but when effects/signals are declared outside any effects solidjs can not do that. if you would like to dispose of the signals/effects yourself you can use createRoot, it passes a dispose function in its callback:
const {dispose} = createRoot((dispose) => {
...
// dispose inside the createRoot
dispose();
// or return it to be used outside of createRoot
return {dispose}
})
setTimeout(() => dispose(), 1000)
const {dispose} = createRoot((dispose) => {
...
// dispose inside the createRoot
dispose();
// or return it to be used outside of createRoot
return {dispose}
})
setTimeout(() => dispose(), 1000)
Mtlive
MtliveOP6mo ago
thanks. but I not sure whether my way of implementing global i18n through createRoot is correct. Is there a more appropriate way in the field of solidjs?
bigmistqke
bigmistqke6mo ago
Your code is syntactically correct 👍 You are not making use of the dispose-callback, so you are not making use of the main reason why you would want to use createRoot, besides suppressing the error. Also important to note: if you are using SSR this pattern (it's called a singleton i think: having a reactive value that you import wherever you need it) will cause issues. With SSR you should do dependency injection with context to not create accidental shared state between different visitors.
Want results from more Discord servers?
Add your server