首页 > 解决方案 > 使用 Context API 设置应用程序设置,而不直接依赖它

问题描述

我正在编写一个带有三个底部标签的应用程序。一个选项卡用于特定于应用程序的设置(与手机的设置无关)。更改其中一些应该反映在应用程序的其余部分中。一项设置切换主题,其余设置仅影响一个选项卡(我们称之为TabA)。React Context API 适合主题并且运行良好。App我使用自定义挂钩在类中加载设置 + 主题,并使用useSettingssetter 函数创建主题上下文。上下文包装了整个应用程序,以便所有选项卡都可以使用它并在主题更改时更新。这里没有惊喜。

但是,我无法找到一种合适的方法来反映TabAContext API 中剩余设置的更改。要获取和设置设置,设置选项卡需要使用设置上下文,但这意味着如果上下文更改,设置选项卡也会重新呈现,即使它只需要访问上下文来设置它但不需要需要依赖它。只能从设置选项卡更改设置。App下面在我的组件的精简版本中说明了在上下文中使用设置。

export const App = () => {
  // Load the settings asynchronously using AsyncStorage. 'setSettings' updates the state in the app
  // while 'commitSettings' saves the current settings to storage
  const [settings, setSettings, commitSettings, setTheme] = useSettings()

  // Get the theme values from the theme's name
  const theme = getTheme(currentTheme)

  // Create a theme context
  const themeContextValue = {
    theme,
    setTheme, // Used to set the current theme from the Settings tab
  }

  // Create a context for the settings
  const settingsContextValue = {
    settings,
    setSettings,
   }

  return (
    <NavigationContainer>
      <ThemeContext.Provider value={themeContextValue}>
        <Tabs.Navigator>
          <SettingsContext.Provider value={settingsContextValue}>
            <Tabs.Screen name="Tab A" component={TabA} />
            <Tabs.Screen name="Settings" component={Settings} />
          </SettingsContext.Provider>
        </Tabs.Navigator>
      </ThemeContext.Provider>
    </NavigationContainer>
  )
}

export const TabA = () => {
  <ThemeContext.Consumer>
    { themeValue => (
      <SettingsContext.Consumer>
        { settingsValue => (...) }
      </SettingsContext.Consumer>
    )}
  </ThemeContext.Consumer>
}

export const Settings = () => {
  // Same context consumption as above
}

这使我认为 Context API 可能不是设置的最佳方法,因为我无法将对上下文的依赖与设置它分离,这不是使用 Context API 的预期方式,无论是 AFAIK。加载和保存设置(使用AsyncStorage)可以工作,但仍然需要我传达TabA设置已更改或每次TabA关注时加​​载设置。当用户在选项卡之间切换时,默认情况下不会卸载选项卡。相反,我可以在选项卡获得焦点时使用和加载设置等订阅焦点/模糊事件。react-navigationRedux用于相对较小的应用程序似乎有点过分了。

理想情况下,Settings选项卡将设置设置而不重新渲染,并且TabA选项卡仅在设置更改(或它依赖的其他内容)时重新渲染。The settings would be committed to storage when eg the Settingstab becomes unfocused. 也许可以改为为App类中的设置创建一个普通状态,并将状态变量TabA和状态设置器Settings作为道具传递给选项卡?一个问题是,App当状态发生变化时,该类将重新呈现,这是不必要的。只TabA需要重新渲染。

我知道这是一个过早的优化,我还没有分析任何东西,但我仍然对设计视角以及React为这种情况提供哪些工具感兴趣。总而言之,如何在不触发更新依赖关系的组件中重新渲染的情况下A从另一个组件更新组件的依赖关系?BBA

我正在使用react@16.13.1, react-native@0.63.3, react-navigation/bottom-tabs@5.5.2,react-navigation/native@5.5.1react-native-community/async-storage@1.12.1.

标签: react-nativetabsreact-navigationasyncstoragereact-context

解决方案


推荐阅读