React-native-navigation 从另一个 tabnavigator 更改状态

标签 react-native react-navigation

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

最佳答案

是的,你可以。它有点复杂,有点hacky,可能有一些副作用,但理论上你可以做到。我创建了一个 working example snack here .

在 react 导航中,您可以 set parameters使用路由键的其他屏幕。

When dispatching SetParams, the router will produce a new state that has changed the params of a particular route, as identified by the key

  • params - object - required - New params to be merged into existing route params
  • key - string - required - Route key that should get the new params

示例

import { NavigationActions } from 'react-navigation'

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

为此,您需要知道要传递参数的屏幕的 key 属性。现在这是我们变得困惑的地方。我们可以结合onNavigationStateChangescreenProps props 获取当前堆栈键,然后将它们作为属性传递给我们当前所在的屏幕。

重要提示:因为在应用首次启动时不会触发 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}}
      />
    );
  }
}

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

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>
    )
  }
}

现在您可以从导航中获取新参数,您可以在屏幕上按原样使用它,也可以在 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});
  }
}

更新

现在 react-navigation 支持监听器,您可以使用这些监听器来检测屏幕的焦点或模糊状态。

addListener - Subscribe to updates to navigation lifecycle

React Navigation emits events to screen components that subscribe to them:

  • willBlur - the screen will be unfocused
  • willFocus - the screen will focus
  • didFocus - the screen focused (if there was a transition, the transition completed)
  • didBlur - the screen unfocused (if there was a transition, the transition completed)

文档中的示例

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',
};

关于React-native-navigation 从另一个 tabnavigator 更改状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46930098/

相关文章:

react-native - 我一直收到 [RCTCxxBridge jsContextRef] 无法识别的选择器发送到实例 0x7f8af262f4f0' 是从 JS 线程抛出的

javascript - 如何增加向上滚动的计数

react-native - 一个 React Native 屏幕可以包含在两个不同的堆栈导航器中吗?

javascript - 使用 NavigationService 在 React 组件之外的 React Native 中导航、弹出、重置

javascript - 在渲染之外使用 Prop

react-native - 如何在 React Native Android 的发布包中包含静态 html?

react-native - 使用 Auth Token header react 原生图像,如何处理 401?

reactjs - 如果应用程序关闭,则 React-Native 深层链接不起作用(React-Navigation v5)

reactjs - 类型错误 : No "routes" found in navigation state

react-native - React Native 中的后退按钮