React-native-navigation从另一个选项卡导航器更改状态

ray*_*shi 2 react-native react-navigation

我正在使用react-navigation / TabNavigator,有没有办法在不使用Redux或mobx的情况下从另一个选项卡更改选项卡的状态?

ben*_*nel 5

是的你可以。它有点复杂,有点怪异,可能会有一些副作用,但是从理论上讲您可以做到。我在这里创建了一个工作示例小吃

在反应导航中,您可以使用路径键为其他屏幕设置参数

调度SetParams时,路由器将产生一个新状态,该状态已更改特定路由的参数,如键所标识

  • 参数 -对象-必需-新参数将合并到现有路径参数中
  • -字符串-必需-应该获取新参数的路由键

import { NavigationActions } from 'react-navigation'

const setParamsAction = NavigationActions.setParams({
  params: { title: 'Hello' },
  key: 'screen-123',
})
this.props.navigation.dispatch(setParamsAction)
Run Code Online (Sandbox Code Playgroud)

为此,您需要了解key要传递参数的屏幕的属性。现在这是我们混乱的地方。我们可以结合onNavigationStateChangescreenProps道具来获得当前栈键,然后将它们传递作为一个属性屏幕我们目前英寸

重要说明:因为onNavigationStateChange在首次启动该应用程序时未触发,所以this.state.keys它将是一个空数组。因此,您需要执行初始导航操作。

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      keys: []
    };
  }
  onNavigationChange = (prevState, currentState) => {
    this.setState({
      keys: currentState.routes
    });
  }
  render() {
    return(
      <Navigation
        onNavigationStateChange={this.onNavigationChange}
        screenProps={{keys: this.state.keys}}
      />
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以使用keysprop来获取所需屏幕的键,然后可以传递所需的参数。

class Tab1 extends Component {
  onTextPress = () => {
    if(this.props.screenProps.keys.length > 0) {
      const Tab2Key = this.props.screenProps.keys.find((key) => (key.routeName === 'Tab2')).key;
      const setParamsAction = NavigationActions.setParams({
        params: { title: 'Some Value From Tab1' },
        key: Tab2Key,
      });
      this.props.navigation.dispatch(setParamsAction);
    }
  }
  render() {
    const { params } = this.props.navigation.state;
    return(
      <View style={styles.container}>
        <Text style={styles.paragraph} onPress={this.onTextPress}>{`I'm Tab1 Component`}</Text>
      </View>
    )
  }
}

class Tab2 extends Component {
  render() {
    const { params } = this.props.navigation.state;
    return(
      <View style={styles.container}>
        <Text style={styles.paragraph}>{`I'm Tab2 Component`}</Text>
        <Text style={styles.paragraph}>{ params ? params.title : 'no-params-yet'}</Text>
      </View>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以从导航中获取新参数,可以按原样使用它,也可以在中更新状态componentWillReceiveProps

componentWillReceiveProps(nextProps) {
  const { params } = nextProps.navigation.state;
  if(this.props.navigation.state.params && params &&  this.props.navigation.state.params.title !== params.title) {
    this.setState({ myStateTitle: params.title});
  }
}
Run Code Online (Sandbox Code Playgroud)

更新

现在,反应导航支持侦听器,您可以使用它们来检测屏幕的焦点或模糊状态。

的addListener -订阅更新导航生命周期

React Navigation将事件发送到订阅它们的屏幕组件:

  • willBlur -屏幕将无法对焦
  • willFocus -屏幕将聚焦
  • didFocus -屏幕聚焦(如果有过渡,则过渡完成)
  • didBlur -屏幕未聚焦(如果有过渡,则过渡完成)

文档中的示例

const didBlurSubscription = this.props.navigation.addListener(
  'didBlur',
  payload => {
    console.debug('didBlur', payload);
  }
);
// Remove the listener when you are done
didBlurSubscription.remove();

// Payload
{
  action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
  context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
  lastState: undefined,
  state: undefined,
  type: 'didBlur',
};
Run Code Online (Sandbox Code Playgroud)