0
votes

I am learning to use React Navigation and loving it, but can't figure out how to send props from my top level App Component down to my screen components. I could be (most probably) going about it completely the wrong way. Here is my code.

Main App Component

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            signedIn: false,
            checkedSignIn: false
        };
    }

    componentWillMount() {
        isSignedIn()
            .then(res => this.setState({ signedIn: res, checkedSignIn: true }))
            .catch(err => alert(err));
    }

    render() {
        const { checkedSignIn, signedIn } = this.state;

        if (!checkedSignIn) {
            return null;
        }

        if (signedIn) {
            console.log("yeah boi");
            console.log(SignedOut);
            return (
                <Provider store={store}>
                    <SignedIn screenProps={(name = "TestName")} />
                </Provider>
            );
        } else {
            console.log("nah bro");
            return (
                <Provider store={store}>
                    <SignedOut />
                </Provider>
            );
        }
    }
}

Screen

export default ({ navigation }) =>
    <View style={{ paddingVertical: 20 }}>
        <Card title="John Doe">
            <View
                style={{
                    backgroundColor: "#bcbec1",
                    alignItems: "center",
                    justifyContent: "center",
                    width: 80,
                    height: 80,
                    borderRadius: 40,
                    alignSelf: "center",
                    marginBottom: 20
                }}
            >
                <Text style={{ color: "white", fontSize: 28 }}>JD</Text>
            </View>
            <Button
                title="SIGN OUT"
                onPress={() =>
                    onSignOut().then(() => navigation.navigate("SignedOut"))} // NEW LOGIC
            />
        </Card>
    </View>;

Nav

export const SignedIn = TabNavigator({
    Tasks: {
        screen: Tasks,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="list" size={30} />
        }
    },
    Home: {
        screen: Home,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="home" size={30} />
        }
    },
    Message: {
        screen: Message,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="envelope-letter" size={30} />
        }
    },
    Profile: {
        screen: Profile,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="user" size={30} />
        }
    }
});

Can anyone tell me how I would pass props, such as my attempted {(name = "TestName")}, to the SignedIn SFC?

I am fairly new to react so please be gentle :)

Thanks Sam

3

3 Answers

1
votes

Got it sorted while still keeping the items stateless, using React Navigations screenProps parameter. Just had to fix my syntax in the Nav component and explicitly call screenProps in my screen. Here it is for reference:

Main App

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            signedIn: false,
            checkedSignIn: false
        };
    }

    componentWillMount() {
        isSignedIn()
            .then(res => this.setState({ signedIn: res, checkedSignIn: true }))
            .catch(err => alert(err));
    }

    render() {
        const { checkedSignIn, signedIn } = this.state;

        if (!checkedSignIn) {
            return null;
        }

        if (signedIn) {
            console.log("yeah boi");
            console.log(SignedOut);
            return (
                <Provider store={store}>
                    <SignedIn screenProps={{ name: "TestName" }} />
                </Provider>
            );
        } else {
            console.log("nah bro");
            return (
                <Provider store={store}>
                    <SignedOut />
                </Provider>
            );
        }
    }
}

Screen

export default ({ navigation, screenProps }) =>
    <View style={{ paddingVertical: 20 }}>
        <Card title={screenProps.name}>
            <View
                style={{
                    backgroundColor: "#bcbec1",
                    alignItems: "center",
                    justifyContent: "center",
                    width: 80,
                    height: 80,
                    borderRadius: 40,
                    alignSelf: "center",
                    marginBottom: 20
                }}
            >
                <Text style={{ color: "white", fontSize: 28 }}>JD</Text>
            </View>
            <Button
                title="SIGN OUT"
                onPress={() =>
                    onSignOut().then(() => navigation.navigate("SignedOut"))} // NEW LOGIC
            />
        </Card>
    </View>;

Nav

export const SignedIn = TabNavigator({
    Tasks: {
        screen: Tasks,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="list" size={30} />
        }
    },
    Home: {
        screen: Home,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="home" size={30} />
        }
    },
    Message: {
        screen: Message,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="envelope-letter" size={30} />
        }
    },
    Profile: {
        screen: Profile,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name="user" size={30} />
        }
    }
});
0
votes

Use store state to get data, set state of store in top level component, use that state in your screen component

0
votes

I think <SignedIn screenProps={(name = "TestName")} /> will rise a syntax error. It should be just <SignedIn name='TestName' />. The bigger problem is how you use the TabNavigator component. What if you try the following:

export const SignedIn = ({ name }) => TabNavigator({
    Tasks: {
        screen: Tasks,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name={ name } size={30} />
        }
    },
    Home: {
        screen: Home,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name={ name } size={30} />
        }
    },
    Message: {
        screen: Message,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name={ name } size={30} />
        }
    },
    Profile: {
        screen: Profile,
        navigationOptions: {
            tabBarIcon: ({ tintColor }) =>
                <SimpleLineIcons name={ name } size={30} />
        }
    }
});