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 🌈
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
Mtlive2d 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 🌈
bigmistqke 🌈21h 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.