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

use*_*627 5 reactjs reactjs-native react-native

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

这是我能做的最简单的例子.

组件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);
Run Code Online (Sandbox Code Playgroud)

组件B.

B在mount上从AsyncStorage读取,然后设置为state.

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;
Run Code Online (Sandbox Code Playgroud)

组件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;
Run Code Online (Sandbox Code Playgroud)

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

我所知道的一个解决方案,但并不理想,是让B的状态成为C的支柱,并给C一个回调道具来切换它.如果B和C总是直接是父和子,那么这将很有效,但在真实应用中,导航层次结构可能更深.

无论如何在导航事件之后触发组件上的功能,或者我缺少的其他东西?

Col*_*say 0

如果您使用 NavigatorIOS,那么它可以将底层导航器传递给每个子组件。您可以在这些组件中使用几个事件:

onDidFocus 函数

转换完成后或初始安装后,将使用每个场景的新路线进行调用

onItemRef 函数

当场景 ref 改变时将被调用 (ref, indexInStack, Route)

onWillFocus 函数

将在安装时和每次导航转换之前发出目标路线

https://facebook.github.io/react-native/docs/navigator.html#content