【问题标题】:Update language using react-intl and mobx state tree使用 react-intl 和 mobx 状态树更新语言
【发布时间】:2021-08-18 13:03:46
【问题描述】:

这是我第一次使用react-intlMobx state tree

基本上,我在标题中有两个按钮(iten),单击它们可以设置保存在 Mobx 状态树变量中的当前语言。

类似的东西。

在我的状态:

const FULL_LANGUAGE =
  (navigator.languages && navigator.languages[0]) || navigator.language || 'en-GB'
const LANGUAGE = FULL_LANGUAGE!.split('-')[0]

export const UIModel = t
  .model('UIModel', {
    language: LANGUAGE,
  })
  .actions((self) => ({
    setLanguage(language: 'it' | 'en') {
      self.language = language
    }
  }))

在标题组件中:

...
<Button textToShow="it" onClick={() => setLanguage('it')} />
<Button textToShow="en" onClick={() => setLanguage('en')} />
...

我的index.tsx 文件:

import React from 'react'
import ReactDOM from 'react-dom'
import { IntlProvider } from 'react-intl'
import { stateInstance, Provider } from './state'
import { App } from './App'
import messagesIt from './locales/messages-it.json5'
import messagesEn from './locales/messages-en.json5'

const language = stateInstance.ui.language
const messages = language === 'en' ? messagesEn : messagesIt

function renderApp() {
  ReactDOM.render(
    <Provider value={stateInstance}>
      <IntlProvider locale={language} messages={messages}>
        <App />
      </IntlProvider>
    </Provider>,
    document.getElementById('root')
  )
}

renderApp()

还有我的 Mobx 状态树根文件:

import { createContext, useContext } from 'react'
import { Instance, types as t } from 'mobx-state-tree'
import { UIModel } from './UI'

export const StateModel = t
  .model('StateModel', {
    ui: t.optional(UIModel, {}),
  })

export const stateInstance = StateModel.create()
export interface StateInstance extends Instance<typeof StateModel> {}

const RootStateContext = createContext<StateInstance | null>(null)
export const Provider = RootStateContext.Provider

export function useMst() {
  const state = useContext(RootStateContext)
  if (state === null) throw new Error('')
  return state
}

问题是当我点击iten 按钮时,状态中的语言会更新,但我认为没有任何变化,因为&lt;IntlProvider locale={language} messages={messages}&gt; 没有“重新渲染”。

我该如何解决?

【问题讨论】:

    标签: javascript reactjs mobx react-intl mobx-state-tree


    【解决方案1】:

    有很多方法可以解决它,例如,我认为您可以将 IntlProvider 包装在 Observer (docs) 组件中以使其具有反应性:

    import { Observer } from 'mobx-react';
    
    // ...
    
    function renderApp() {
      ReactDOM.render(
        <Provider value={stateInstance}>
          <Observer>
            {() => (
              <IntlProvider
                locale={stateInstance.ui.language}
                messages={
                  stateInstance.ui.language === 'en' ? messagesEn : messagesIt
                }
              >
                <App />
              </IntlProvider>
            )}
          </Observer>
        </Provider>,
        document.getElementById('root')
      );
    }
    

    【讨论】:

      【解决方案2】:

      这样解决:

      const AppContainer: React.FC<{}> = observer(({}) => {
        const {
          ui: { language },
        } = useMst()
        return (
          <IntlProvider locale={language} messages={language === 'en' ? messagesEn : messagesIt}>
            <App />
          </IntlProvider>
        )
      })
      
      function renderApp() {
        ReactDOM.render(
          <Provider value={stateInstance}>
            <AppContainer />
          </Provider>,
          document.getElementById('root')
        )
      }
      

      【讨论】:

      • 是的,也是不错的解决方案!如果问题已解决,请标记为已接受,谢谢。
      猜你喜欢
      • 1970-01-01
      • 2016-11-04
      • 2021-07-09
      • 2020-05-22
      • 2016-06-17
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 2017-10-10
      相关资源
      最近更新 更多