35

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

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

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

这个问题指的onDisplay是我正在寻找的东西。但是我找不到任何关于它的官方文档 - https://github.com/wix/react-native-navigation/issues/130

4

8 回答 8

40

我喜欢 Bruno Reis 提出的解决方案。我调整了我的让它更简单一些。

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

}
于 2018-06-21T03:43:20.963 回答
5

将其包含为“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()
    )
}
于 2018-05-26T00:17:24.880 回答
5

文档中,它表明您可以像这样添加焦点事件:

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
于 2021-03-31T13:24:01.023 回答
4

对于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()。

于 2019-09-24T13:44:27.257 回答
2

这就是我最终使用的:

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()在屏幕上(根据 screenProps 可能会或可能不会执行某些操作currentScreen)。

注意:我不知道是什么/在哪里getCurrentRouteName(),它给了我错误,所以我不使用它并action.routeName直接使用。

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

于 2017-08-28T12:35:53.240 回答
1

当前接受的答案建议使用 react-navigation 解决方案,而不是 react-native-navigation (RNN),所以我会继续给我两分钱。

正如 Stephen Liu 在他的回答中指出的那样,RNN 提供了在组件出现 ( ) 和消失 ( )时触发的屏幕生命周期方法componentDidAppearcomponentDidDisappear

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需要一个componentIdprop,如果它是注册的 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!
  })

}
于 2019-11-18T21:23:40.227 回答
1

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

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

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

于 2021-06-30T14:34:49.940 回答
-4

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

于 2016-10-17T12:50:24.060 回答