20

我按照以下示例使用 React Navigator 创建了一个多屏应用程序:

import {
  createStackNavigator,
} from 'react-navigation';

const App = createStackNavigator({
  Home: { screen: HomeScreen },
  Profile: { screen: ProfileScreen },
});

export default App;

现在我想使用新的内置上下文 api添加一个全局配置状态,这样我就可以拥有一些可以从多个屏幕进行操作和显示的通用数据。

问题是上下文显然需要具有公共父组件的组件,因此可以将上下文传递给子组件。

据我所知,我如何使用不共享共同父级的屏幕来实现这一点,因为它们是由反应导航器管理的?

4

3 回答 3

27

你可以把它变成这样。

创建新文件:GlobalContext.js

import React from 'react';

const GlobalContext = React.createContext({});

export class GlobalContextProvider extends React.Component {
  state = {
    isOnline: true
  }

  switchToOnline = () => {
    this.setState({ isOnline: true });
  }

  switchToOffline = () => {
    this.setState({ isOnline: false });
  }

  render () {
    return (
      <GlobalContext.Provider
        value={{
          ...this.state,
          switchToOnline: this.switchToOnline,
          switchToOffline: this.switchToOffline
        }}
      >
        {this.props.children}
      </GlobalContext.Provider>
    )
  }
}

// create the consumer as higher order component
export const withGlobalContext = ChildComponent => props => (
  <GlobalContext.Consumer>
    {
      context => <ChildComponent {...props} global={context}  />
    }
  </GlobalContext.Consumer>
);

index.js使用上下文提供程序组件包装您的根组件时。

<GlobalContextProvider>
  <App />
</GlobalContextProvider>

然后在你的屏幕上HomeScreen.js使用这样的消费者组件。

import React from 'react';
import { View, Text } from 'react-native';
import { withGlobalContext } from './GlobalContext';

class HomeScreen extends React.Component {
  render () {
    return (
      <View>
        <Text>Is online: {this.props.global.isOnline}</Text>
      </View>
    )
  }
}

export default withGlobalContext(HomeScreen);

您还可以创建多个上下文提供者来分离您的关注点,并在您想要的屏幕上使用 HOC 消费者。

于 2018-08-13T14:50:54.473 回答
2

这个答案考虑了react-navigation包。

您必须用 包装您的App组件ContextProvider才能在两个屏幕上访问您的上下文。

    import { createAppContainer } from 'react-navigation'
    import { createStackNavigator } from 'react-navigation-stack'
    import ProfileContextProvider from '../some/path/ProfileContextProvider'

    const RootStack = createStackNavigator({
      Home: { screen: HomeScreen },
      Profile: { screen: ProfileScreen },
    });

    const AppContainer = createAppContainer(RootStack)    
    const App = () => {
      return (
      <ProfileContextProvider>
        <AppContainer />
      </ProfileContextProvider>);
    }
于 2019-11-23T22:22:41.853 回答
1

https://wix.github.io/react-native-navigation/docs/third-party-react-context/

由于 RNN 屏幕不是同一组件树的一部分,因此更新共享上下文中的值不会触发跨所有屏幕的重新渲染。但是,您仍然可以使用每个 RNN 屏幕组件树的 React.Context。

如果您需要在所有屏幕上触发重新渲染,有许多流行的第三方库,例如 MobX 或 Redux。

于 2020-11-15T09:07:50.720 回答