我按照以下示例使用React Navigator创建了一个多屏应用程序:
import {
createStackNavigator,
} from 'react-navigation';
const App = createStackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
export default App;
现在,我想使用the new builtin context api添加全局配置状态,这样我可以拥有一些可以在多个屏幕上进行操作和显示的通用数据。
问题是上下文显然需要具有公共父组件的组件,以便可以将上下文传递给子组件。
我如何使用我所知的不共享公共父屏幕的屏幕来实现此目的,因为它们是由react导航器管理的?
答案 0 :(得分:12)
您可以这样做。
创建新文件: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使用者。
答案 1 :(得分:1)
此答案包含考虑因素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 />
</UserContextProvider>);
}
答案 2 :(得分:0)
如果您想了解详细的教程,可以点击以下链接: 访问:https://www.thelearninguy.com/simple-react-native-context-api-detailed
很长的答案如下。
import React, {Component} from 'react';
import {Text, View, Button} from 'react-native';
//make a new context
const MyContext = React.createContext();
//create provider component
class MyProvider extends Component {
state = {
name: "The Learnin Guy",
age: 50
};
increaseAge = () => {
this.setState({
age: this.state.age + 1
});
};
render() {
return (
<MyContext.Provider
value={{
state: this.state,
increaseAge: this.increaseAge
}}
>
{this.props.children}
</MyContext.Provider>
);
}
}
class Person extends Component {
render() {
return (
<View>
<Text>This is Person Component</Text>
<MyContext.Consumer>
{(context) => (
<React.Fragment>
<Text>Name: {context.state.age}</Text>
<Text>Age: {context.state.age}</Text>
<Button title="IncreaseAge" onPress={context.increaseAge} />
</React.Fragment>
)}
</MyContext.Consumer>
</View>
);
}
}
class Family extends Component {
render() {
return (
<View>
<Text>This is Family Component</Text>
<MyContext.Consumer>
{(context) => (
<React.Fragment>
<Text>Age: {context.state.age}</Text>
</React.Fragment>
)}
</MyContext.Consumer>
<Person/>
</View>
);
}
}
class App extends Component {
render() {
return (
<MyProvider>
<View>
<Text>This is App Component</Text>
<MyContext.Consumer>
{(context) => (
<React.Fragment>
<Text>Age: {context.state.age}</Text>
</React.Fragment>
)}
</MyContext.Consumer>
<Family/>
</View>
</MyProvider>
);
}
}
export default App;
答案 3 :(得分:0)
https://wix.github.io/react-native-navigation/docs/third-party-react-context/
由于RNN屏幕不是同一组件树的一部分,因此在共享上下文中更新值不会触发所有屏幕的重新渲染。但是,您仍然可以按每个RNN屏幕组件树使用React.Context。
如果您需要在所有屏幕上触发重新渲染,则有许多流行的第三方库,例如MobX或Redux。