reactjs - react native 组件生命周期方法不会在导航时触发

标签 reactjs react-native reactjs-native

我遇到一个问题,我根据 AsyncStorage 中的相同键在多个组件中设置状态。由于状态是在 componentDidMount 中设置的,并且这些组件不一定在导航时卸载和安装,因此状态值和 AsyncStorage 值可能会不同步。

这是我能举的最简单的例子。

组件A

A 只是设置导航和应用程序。

var React = require('react-native');
var B = require('./B');

var {
    AppRegistry,
    Navigator
} = React;

var A = React.createClass({
    render() {
        return (
            <Navigator
                initialRoute={{
                    component: B
                }}
                renderScene={(route, navigator) => {
                    return <route.component navigator={navigator} />;
                }} />
        );
    }
});

AppRegistry.registerComponent('A', () => A);

组件B

B 在挂载时从 AsyncStorage 读取,然后设置为状态。

var React = require('react-native');
var C = require('./C');

var {
    AsyncStorage,
    View,
    Text,
    TouchableHighlight
} = React;

var B = React.createClass({
    componentDidMount() {
        AsyncStorage.getItem('some-identifier').then(value => {
            this.setState({
                isPresent: value !== null
            });
        });
    },

    getInitialState() {
        return {
            isPresent: false
        };
    },

    goToC() {
        this.props.navigator.push({
            component: C
        });
    },

    render() {
        return (
            <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
                <Text>
                    {this.state.isPresent
                        ? 'Value is present'
                        : 'Value is not present'}
                </Text>

                <TouchableHighlight onPress={this.goToC}>
                    <Text>Click to go to C</Text>
                </TouchableHighlight>
            </View>
        );
    }
});

module.exports = B;

组件C

C 从 AsyncStorage 读取与 B 相同的值,但允许您更改该值。更改会切换状态和 AsyncStorage 中的值。

var React = require('react-native');
var {
    AsyncStorage,
    View,
    Text,
    TouchableHighlight
} = React;

var C = React.createClass({
    componentDidMount() {
        AsyncStorage.getItem('some-identifier').then(value => {
            this.setState({
                isPresent: value !== null
            });
        });
    },

    getInitialState() {
        return {
            isPresent: false
        };
    },

    toggle() {
        if (this.state.isPresent) {
            AsyncStorage.removeItem('some-identifier').then(() => {
                this.setState({
                    isPresent: false
                });
            })
        } else {
            AsyncStorage.setItem('some-identifier', 'some-value').then(() => {
                this.setState({
                    isPresent: true
                });
            });
        }
    },

    goToB() {
        this.props.navigator.pop();
    },

    render() {
        return (
            <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
                <Text>
                    {this.state.isPresent
                        ? 'Value is present'
                        : 'Value is not present'}
                </Text>

                <TouchableHighlight onPress={this.toggle}>
                    <Text>Click to toggle</Text>
                </TouchableHighlight>

                <TouchableHighlight onPress={this.goToB}>
                    <Text>Click to go back</Text>
                </TouchableHighlight>
            </View>
        );
    }
});

module.exports = C;

如果您在 C 中切换然后返回 B,则 B 中的状态和 AsyncStorage 中的值现在不同步。据我所知, navigator.pop() 不会触发任何我可以用来告诉 B 刷新值的组件生命周期函数。

我知道但并不理想的一个解决方案是使 B 的状态成为 C 的支柱,并为 C 提供回调支柱来切换它。如果 B 和 C 始终是直接的父级和子级,那么效果会很好,但在真正的应用程序中,导航层次结构可能会更深。

是否有办法在导航事件之后触发组件上的函数,或者我缺少的其他内容?

最佳答案

遇到了和你一样的问题。我希望这能得到改变,或者我们在组件上获得一个额外的事件来监听(componentDidRenderFromRoute)或类似的东西。无论如何,我解决这个问题的方法是将父组件保留在范围内,以便子导航栏可以调用组件上的方法。我正在使用:https://github.com/Kureev/react-native-navbar ,但它只是 Navigator 的包装:

class ProjectList extends Component {
  _onChange(project) {
    this.props.navigator.push({
      component: Project,
      props: { project: project },
      navigationBar: (<NavigationBar
        title={project.title}
        titleColor="#000000"
        style={appStyles.navigator}
        customPrev={<CustomPrev onPress={() => {
          this.props.navigator.pop();
          this._sub();
        }} />}
      />)
    });
  }
}

我正在推送带有 Prop 数据的项目组件,并附加了我的导航栏组件。 customPrev 是react-native-navbar 将替换为其默认值的内容。因此,在按下时,我调用 pop,并在我的 ProjectList 实例上调用 _sub 方法。

关于reactjs - react native 组件生命周期方法不会在导航时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30768595/

相关文章:

reactjs - 如何在reactjs中使用azure ad应用身份验证2因素?

android - React Native Android - 如何仅在设备上以 Debug模式运行?

ios - 当应用程序未在 React-Native firebase 中运行时如何设置通知声音

facebook-graph-api - 在react-native中使用FB JS sdk进行用户认证

javascript - await 是 async 函数内部的保留字错误

javascript - 无法读取未定义的属性 'map'(React JS 和 AJAX)

javascript - 当其他组件的状态发生变化时如何获取

javascript - react native 相机,onBarCodeRead 不起作用

javascript - 基于另一列聚合React中表中一列的值