在动画场景之外控制 StackNavigator
Control StackNavigator outside of the animated scene
编辑:我了解我的问题和解决方案,所以我重新表述我的问题,然后给出答案。
正常 StackNavigator
和带导航的屏幕如下所示:
class ExampleScreen extends React.Component {
render() {
const { navigate, state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
<Button
title="Click"
onPress={() => {
navigate('Example', { exampleTitle: 'foo' })
}}
/>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: { exampleTitle: 'bar' }
});
AppRegistry.registerComponent('Example', () => ExampleNavigator);
我想访问 ExampleScreen#render
之外的 navigation
对象,这样它就不是 CardStack
动画的一部分。
我通过添加另一个屏幕来渲染解决了我的问题 ExampleNavigator
并且
在 ExampleNavigator
上设置 ref
属性。 navigation
对象和
路由参数的访问方式略有不同,但我将在下面的注释中解释整个代码。
class ExampleScreen extends React.Component {
render() {
const { state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: { exampleTitle: 'bar' }
});
// my solution
class RootScreen extends React.Component {
constructor(props) {
super(props);
// makes sure _onPress has the correct context when clicked
this._onPress = this._onPress.bind(this);
}
render() {
// flex: 1 is set to make the navigator visible. you wont see the navigator
// without this.
return (
<View style={{flex: 1}}>
<ExampleNavigator ref='nav' />
<Button title='Click' onPress={this._onPress} />
</View>
);
}
_onPress() {
// read navigate and state from _navigation
const { navigate, state } = this.refs.nav._navigation;
const { routes, index } = state;
// read scene params through the route of the index passed in state
const params = routes[index].params;
const exampleTitle = params.exampleTitle + ' clicked';
// use the navigate method as your normally would
navigate('Example', {exampleTitle});
}
}
AppRegistry.registerComponent('Example', () => RootScreen);
我相信我想做的事情与此非常相似,即使不完全相同。我不明白为什么这不是很常见(从组件中提取行为并允许更高级别的组件定义一组组件的行为,在这种情况下定义所有导航行为)而无需使用 refs .
一个理想的解决方案似乎是:
class ExampleScreen extends React.Component {
render() {
const { navigate, state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
<Button
title="Click"
onPress=state.params.onPress
/>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: {
exampleTitle: 'bar',
onPress: () => {XXX.navigate('Example', { exampleTitle: 'foo' })}
}
});
AppRegistry.registerComponent('Example', () => ExampleNavigator);
导航以某种方式在 StackNavigator initialRouteParams 中可用。
我是否还遗漏了一些似乎普遍预期的设计模式的简单解决方案?
编辑:我了解我的问题和解决方案,所以我重新表述我的问题,然后给出答案。
正常 StackNavigator
和带导航的屏幕如下所示:
class ExampleScreen extends React.Component {
render() {
const { navigate, state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
<Button
title="Click"
onPress={() => {
navigate('Example', { exampleTitle: 'foo' })
}}
/>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: { exampleTitle: 'bar' }
});
AppRegistry.registerComponent('Example', () => ExampleNavigator);
我想访问 ExampleScreen#render
之外的 navigation
对象,这样它就不是 CardStack
动画的一部分。
我通过添加另一个屏幕来渲染解决了我的问题 ExampleNavigator
并且
在 ExampleNavigator
上设置 ref
属性。 navigation
对象和
路由参数的访问方式略有不同,但我将在下面的注释中解释整个代码。
class ExampleScreen extends React.Component {
render() {
const { state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: { exampleTitle: 'bar' }
});
// my solution
class RootScreen extends React.Component {
constructor(props) {
super(props);
// makes sure _onPress has the correct context when clicked
this._onPress = this._onPress.bind(this);
}
render() {
// flex: 1 is set to make the navigator visible. you wont see the navigator
// without this.
return (
<View style={{flex: 1}}>
<ExampleNavigator ref='nav' />
<Button title='Click' onPress={this._onPress} />
</View>
);
}
_onPress() {
// read navigate and state from _navigation
const { navigate, state } = this.refs.nav._navigation;
const { routes, index } = state;
// read scene params through the route of the index passed in state
const params = routes[index].params;
const exampleTitle = params.exampleTitle + ' clicked';
// use the navigate method as your normally would
navigate('Example', {exampleTitle});
}
}
AppRegistry.registerComponent('Example', () => RootScreen);
我相信我想做的事情与此非常相似,即使不完全相同。我不明白为什么这不是很常见(从组件中提取行为并允许更高级别的组件定义一组组件的行为,在这种情况下定义所有导航行为)而无需使用 refs .
一个理想的解决方案似乎是:
class ExampleScreen extends React.Component {
render() {
const { navigate, state } = this.props.navigation.navigate;
const exampleTitle = state.params.title;
return (
<View>
<Text>{exampleTitle}</Text>
<Button
title="Click"
onPress=state.params.onPress
/>
</View>
);
}
}
const ExampleNavigator = StackNavigator({
Example: { screen: ExampleScreen }
}, {
initialRouteName: 'Example',
initialRouteParams: {
exampleTitle: 'bar',
onPress: () => {XXX.navigate('Example', { exampleTitle: 'foo' })}
}
});
AppRegistry.registerComponent('Example', () => ExampleNavigator);
导航以某种方式在 StackNavigator initialRouteParams 中可用。
我是否还遗漏了一些似乎普遍预期的设计模式的简单解决方案?