使用React-Native-Router-Flux显示不同的组件,具体取决于登录状态

时间:2016-12-21 00:57:30

标签: javascript reactjs meteor react-native react-native-router-flux

我的应用正在使用react-native-router-flux来决定向用户显示哪个组件,具体取决于用户是否

  • 登录或等待应用连接到后端(显示<Loading />
  • 已登录(显示<Home />
  • 未登录(显示<Welcome />

建议的方法是什么?

此示例工作正常,但不使用react-native-router-flux。无论如何修改代码以使用react-native-router-flux

在下面的尝试中,在调用Actions.loading()函数之前调用render会产生错误,因为尚未定义Actions。可以在if函数之后调用render语句吗?

此外,每次更新道具时,都会导致App的重新渲染,从而导致场景键已经存在的错误。

import React, { Component } from 'react';
import Meteor, { createContainer } from 'react-native-meteor';
import { Actions } from 'react-native-router-flux';

import Home from './components/home';
import Welcome from './components/welcome';
import Loading from './components/loading';
import settings from './config/settings';


Meteor.connect(settings.METEOR_URL);


const App = (props) => {

    const { status, user, loggingIn } = props;

    if (status.connected == false || loggingIn) {
        // Render <Loading />
        Actions.loading();
    } else if (user !== null) {
        // Render <Home />
        Actions.home();
    } else {
        // Render <Welcome />
        Actions.welcome();
    }

    return (
        <Router>
            <Scene key="root">
                <Scene key="home" component={Home} title="Home" hideNavBar={true} />
                <Scene key="welcome" component={Welcome} title="Welcome" hideNavBar={true} />
                <Scene key="loading" component={Loading} title="Loading" hideNavBar={true} />
            </Scene>
        </Router>
    )
}


export default createContainer(() => {
    return {
        status: Meteor.status(),
        user: Meteor.user(),
        loggingIn: Meteor.loggingIn()
    };
}, App)

使用Dispatch组件

时出现问题

根据abeikverdi的建议,我创建了以下Dispatch组件,其中包含显示其中一个组件<Loading /><Home /><Welcome />的逻辑。< / p>

问题:this.props.status.connectedtrue(React Native应用程序连接到Meteor后端)时,this.props.user始终为null一段时间之前React Native应用程序从Meteor后端接收此数据。但由于它最初被评估为nullAction.welcome()将被执行。如果this.props.user在一两秒钟后最终变为null并且用户应该被重定向到Actions.home(),则此行为不正确。

有什么想法吗?

export class Dispatch extends Component {
    constructor(props) {
        super(props);
    }

    componentWillUpdate() {
        if(this.props.status.connected == false) {
            Actions.loading();
        } else {
            console.log('meteor.user(): ', Meteor.user())
            if (this.props.user !== null) {
                Actions.home();
            } else {
                Actions.welcome();
            }
        }
    }

    render() {
        return (
            <View></View>
        )
    }
}


export default createContainer(() => {
    return {
        status: Meteor.status(),
        user: Meteor.user(),
        loggingIn: Meteor.loggingIn()
    };
}, Dispatch);
来自日志react-native log-android

错误/警告

以下是React Native应用程序启动一段时间后的Android日志输出,然后通过终止Meteor服务器将其与Meteor(DDP)服务器断开连接。

使用console.log("<App /> render"),似乎每当Meteor的render传递新的props后再次调用createContainer函数时,Key is already defined错误被触发。

无论如何要摆脱这个错误/警告?

12-23 02:27:01.875 31197 19338 I ReactNativeJS: Running application "RNapp" with appParams: {"initialProps":{},"rootTag"
:1}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF
12-23 02:27:01.891 31197 19338 I ReactNativeJS: render
12-23 02:27:01.995 31197 19338 I ReactNativeJS: Connected to DDP server.
12-23 02:27:01.999 31197 19338 I ReactNativeJS: Connected to DDP server.
12-23 02:27:02.012 31197 19338 I ReactNativeJS: render
12-23 02:27:02.013 31197 19338 I ReactNativeJS: Key home is already defined!
12-23 02:27:02.013 31197 19338 I ReactNativeJS: Key welcome is already defined!
12-23 02:27:02.013 31197 19338 I ReactNativeJS: Key loading is already defined!
12-23 02:27:02.013 31197 19338 I ReactNativeJS: Key root is already defined!
12-23 02:27:34.592 31197 19338 I ReactNativeJS: Disconnected from DDP server.
12-23 02:27:34.593 31197 19338 I ReactNativeJS: Disconnected from DDP server.
12-23 02:27:34.599 31197 19338 I ReactNativeJS: <App /> render
12-23 02:27:34.599 31197 19338 I ReactNativeJS: Key home is already defined!
12-23 02:27:34.599 31197 19338 I ReactNativeJS: Key welcome is already defined!
12-23 02:27:34.599 31197 19338 I ReactNativeJS: Key loading is already defined!
12-23 02:27:34.599 31197 19338 I ReactNativeJS: Key root is already defined!
12-23 02:27:34.609 31197 19338 I ReactNativeJS: <Loading /> render
12-23 02:27:35.603 31197 19338 I ReactNativeJS: Disconnected from DDP server.
12-23 02:27:35.613 31197 19338 I ReactNativeJS: <App /> render
12-23 02:27:35.613 31197 19338 I ReactNativeJS: Key home is already defined!
12-23 02:27:35.613 31197 19338 I ReactNativeJS: Key welcome is already defined!
12-23 02:27:35.613 31197 19338 I ReactNativeJS: Key loading is already defined!
12-23 02:27:35.613 31197 19338 I ReactNativeJS: Key root is already defined!
12-23 02:27:45.599 31197 19338 I ReactNativeJS: Disconnected from DDP server.
12-23 02:27:45.616 31197 19338 I ReactNativeJS: <App /> render
12-23 02:27:45.616 31197 19338 I ReactNativeJS: Key home is already defined!
12-23 02:27:45.616 31197 19338 I ReactNativeJS: Key welcome is already defined!
12-23 02:27:45.616 31197 19338 I ReactNativeJS: Key loading is already defined!
12-23 02:27:45.616 31197 19338 I ReactNativeJS: Key root is already defined!

App组件

export class App extends Component {

    constructor(props) {
        super(props);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.status.connected == false) {
            Actions.loading();
        } else {
            if (nextProps.user !== null) {
                Actions.home();
            } else {
                Actions.welcome();
            }
        }
    }


    render() {
       console.log('<App /> render')
        return (
            <Router>
                <Scene key="root">
                    <Scene key="home" component={Home} title="Home" hideNavBar={true} />
                    <Scene key="welcome" component={Welcome} title="Welcome" hideNavBar={true} />
                    <Scene key="loading" component={Loading} title="Loading" hideNavBar={true} />
                    <Scene key="profile" component={Profile} title="Home" hideNavBar={true} />
                    <Scene key="history" component={History} title="Home" hideNavBar={true} />
                    <Scene key="search" component={Search} title="Home" hideNavBar={true} />
                </Scene>
            </Router>
        )       
    }

}


export default createContainer(() => {
  return {
    status: Meteor.status(),
    user: Meteor.user(),
    loggingIn: Meteor.loggingIn(),
  };
}, App);

2 个答案:

答案 0 :(得分:2)

您可以通过使用初始道具来实现这一点,您可以从商店中读取将指示用户是否登录的数据,例如使用access_token。

然后使用initial = {access_token} //例如

但请记住,它会显示最初的道具等于真的最后一个场景

// in componentDidMount
const currentUserAccessToken = store.getState().currentUserAccessToken;
        <Scene
            component={SignIn}
            hideNavBar
            initial={!currentUserAccessToken}
            key="signIn"
            title={I18n.t('sign_in')}
        />

答案 1 :(得分:1)

您可以制作调度页面并将逻辑放在那里。所以只需将Dispatch添加为场景,然后从那里导航。

return (
        <Router>
            <Scene key="root">
                <Scene key="dispatch" component={Dispatch} hideNavBar={true} initial={true} />
                <Scene key="home" component={Home} title="Home" hideNavBar={true} />
                <Scene key="welcome" component={Welcome} title="Welcome" hideNavBar={true} />
                <Scene key="loading" component={Loading} title="Loading" hideNavBar={true} />
            </Scene>
        </Router>
    )

更新:
好像meteor正在将这些参数传递给道具。添加新道具后,componentWillUpdate()将不会被触发。相反,您应该在Actions中通过componentWillReceiveProps(nextProps)将导航逻辑放在下面:

componentWillReceiveProps(nextProps) {
    if(nextProps.status.connected == false) {
        Actions.loading();
    } else {
        console.log('meteor.user(): ', Meteor.user())
        if (this.props.user !== null) {
            Actions.home();
        } else {
            Actions.welcome();
        }
    }
}

然后在登录功能完成后应触发导航逻辑。这应该可以解决问题。