如何在使用react-native-navigation时显示组件时触发事件?

时间:2016-10-17 11:46:41

标签: react-native react-native-navigation

我正在使用react-native和react-native-navigation。我想在显示组件时重新加载数据。当用户单击选项卡导航按钮时,将显示该组件。

我应该使用反应生命周期事件还是反应原生导航中的某些内容可以在用户导航回组件时触发功能?

我正在使用redux,我不确定这是否可以用来帮助?

此问题涉及onDisplay,这似乎就是我要找的内容。但是我找不到任何关于它的官方文档 - https://github.com/wix/react-native-navigation/issues/130

8 个答案:

答案 0 :(得分:20)

我喜欢Bruno Reis提出的解决方案。我调整了我的代码使其变得更简单。

class Whatever extends Component {
    componentDidMount(){
        this.load()
        this.props.navigation.addListener('willFocus', this.load)
    }
    load = () => {
        ...
    }

}

答案 1 :(得分:2)

将此列为' callIfBackToThisRoute' ...

export default ( props, call ) => {
    if( !props.navigation ) throw 'I need props.navigation'
    const thisRoute = props.navigation.state.routeName;
    props.navigation.addListener(
        'willFocus',
        payload => {
            if( payload.state.routeName == thisRoute) call(props)
        }
    );
}

并在你的组件中使用它......

componentDidMount() {
    const { doIt } = this.props;
    doIt()
    callIfBackToThisRoute(
        this.props,
        (props) => doIt()
    )
}

答案 2 :(得分:2)

documentation 中,它显示您可以像这样添加焦点事件:

import React, { useEffect } from 'react'

const MyComponent = ({ navigation }) => {

    useEffect(() => {
        const unsubscribe = navigation.addListener('focus', () => {
            // do something
            console.log('Hello World!')
        });
        return unsubscribe;
    }, [navigation]);

    return (
        <View>
            <Text>MyComponent</Text>
        </View>
    )
}

export default MyComponent

答案 3 :(得分:1)

这是我最终使用的:

.setTrigger(Trigger.executionWindow(0, 60))

与屏幕上的public static String retrieveStream(String link, String parameters) { try { link = link.replace(" ", "%20"); // parameters = parameters.replace(" ", "%20"); URL url = new URL(link); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestMethod("POST"); OutputStreamWriter request = new OutputStreamWriter( connection.getOutputStream()); request.write(parameters); request.flush(); request.close(); String line = ""; InputStreamReader isr = new InputStreamReader( connection.getInputStream()); BufferedReader reader = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line); } // Response from server after login process will be stored in // response variable. String response = sb.toString(); // You can perform UI operations here isr.close(); reader.close(); return response; } catch (IOException ignored) { ignored.printStackTrace(); } return ""; } 结合使用(根据screenProps的export default class RootNavigator extends React.Component { state = {currentScreen: null} _onNavigationStateChange(prevState, newState, action) { // const currentScreen = getCurrentRouteName(currentState) // const prevScreen = getCurrentRouteName(prevState) // console.debug('onNavigationStateChange currentScreen=', currentScreen, // 'prevScreen=', prevScreen, 'action.routeName=', action.routeName) console.debug('onNavigationStateChange action.routeName=', action.routeName) this.setState({currentScreen: action.routeName}) } render() { return <RootStackNavigator onNavigationStateChange={this._onNavigationStateChange.bind(this)} screenProps={{currentScreen: this.state.currentScreen}}/>; } 可能会执行或不执行某些操作。)

注意:我不知道componentDidUpdate()是什么/哪里,但它给了我错误,所以我不使用它并直接使用currentScreen

有关详细信息和讨论,请参阅https://github.com/react-community/react-navigation/issues/2371https://github.com/react-community/react-navigation/issues/51#issuecomment-323536642

答案 4 :(得分:0)

对于RNN v3,在尝试了很多次之后,我终于找到了正确的方法:

  componentDidMount() {
    this.navigationEventListener = Navigation.events().bindComponent(this);
  }

  componentWillUnmount() {
    if (this.navigationEventListener) {
      this.navigationEventListener.remove();
    }
  }

  componentDidAppear() {   // Lazy loading data for RNN
    if (this.state.routes.length === 0) {
      this.getData();
    }
  }

关键是事件监听器的绑定是强制性的,否则componentDidAppear()和componentDidDisappear()不会被触发。

答案 5 :(得分:0)

当前接受的答案提出了一种反应导航解决方案,而不是反应本地导航(RNN),所以我继续讲两分钱。

正如Stephen Liu在其回答中指出的那样,RNN提供screen lifecycle methods,当某个组件出现(componentDidAppear)并消失(componentDidDisappear)时触发。

Stephen的答案适用于类组件,但是在钩子时代,我更喜欢使用功能组件。因此,这就是在功能组件中使用RNN的屏幕生命周期方法的方法:

import React, { useEffect } from 'react'
import { Navigation } from 'react-native-navigation'

const MyComponent = ({ componentId }) => {

  useEffect(() => {
    const navListener = Navigation.events().bindComponent(this, componentId)

    // remove the listener during cleanup
    return () => {
      navListener.remove()
    }
  }, [componentId])

  this.componentDidAppear = () => {
    // do stuff when component appears
  }

  this. componentDidDisappear = () => {
    // do stuff when component disappears
  }

}

重要MyComponent需要一个componentId道具,如果它是已注册的RNN屏幕或模态(Navigation.registerComponent),则会自动注入。您也可以将其从屏幕组件手动传递到所需的子组件。

???奖金:useComponentDidAppear???

我在项目中经常使用RNN的componentDidAppear,所以我制作了一个自定义钩子,可以在整个功能组件中轻松地重用它:

export const useComponentDidAppear = (componentId, callback) => {
  useEffect(() => {
    const navListener = Navigation.events().bindComponent(this, componentId)
    return () => {
      navListener.remove()
    }
  }, [componentId])

  this.componentDidAppear = () => {
    callback()
  }
}

// then use it like this
const SomeScreen = ({ componentId }) => {

  useComponentDidAppear(componentId, () => {
    // do stuff when the component appears!
  })

}

答案 6 :(得分:0)

我在自己的一个项目中遇到了同样的情况,并通过反应导航使用 useFocusEffect 钩子来解决它

有关更多信息,您可以参考有关此的文档

https://reactnavigation.org/docs/function-after-focusing-screen#triggering-an-action-with-the-usefocuseffect-hook

答案 7 :(得分:-2)

覆盖componentWillMount生命周期方法: https://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount 或者只是将功能放在渲染方法