In my app, the LoginScreen(fristScreen) could login with facebook and when the user successfully login, the app receives a facebook access token
and navigates to the next screen(VerifyScreen). In the VerifyScreen(secondScreen), when I click a button I want to bring the global state facebookToken
and display on screen. Below is my code:
App.js
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { createDrawerNavigator, createStackNavigator, } from 'react-navigation'
const reducer = (state = '', action) => {
switch (action.type) {
case 'UPDATE':
return { facebookToken: action.payload}
}
return state
}
const store = createStore(reducer)
class App extends Component {
render(){
return(
<Provider store={store}>
<View style={{flex:1,backgroundColor:'transparent'}}>
<AppDrawerNavigator/>
</View>
</Provider>
)
}
}
LoginScreen.js
import { LoginButton, AccessToken } from 'react-native-fbsdk';
import {connect} from 'react-redux'
class LoginScreen extends Component{
<View>
<LoginButton
onLoginFinished={
(error, result) => {
if (error) {
console.log("login has error: " + result.error);
} else if (result.isCancelled) {
console.log("login is cancelled.");
} else {
this.props.navigation.navigate('VerifyScreen')
AccessToken.getCurrentAccessToken().then(
(data) => {
this.setState({facebookToken:data.accessToken},
() => console.log('facebookToken.state',this.state.facebookToken),
//Here I am getting undefined for 'this.props.facebookToken'
() => console.log('facebookToken.props',this.props.facebookToken),
console.log('facebook login success!'),
console.log('facebook token is:',data.accessToken.toString()))
}
)
}
}
}
onLogoutFinished={() => console.log("logout.")}/>
//I created a button to see if I could call global state. but this would give me an error "state is not defined"
<Button
title="call global state"
onPress={() => this.props.increaseCounter()}/>
</View>
function mapStateToProps(state) {
return {
facebookToken: state.facebookToken
}
}
function mapDispatchToProps(dispatch) {
return {
increaseCounter: () => dispatch({ type: 'UPDATE',payload: state.facebookToken }),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)
VerifyScreen.js
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
Button
} from "react-native";
import {connect} from 'react-redux'
class VerifyScreen extends Component {
render() {
return (
<View>
<Button
title="Get facebook Access Token"
onPress={()=>
//I get undefined data when I console.log
console.log(this.state.facebookToken,'this.state.facebookToken')}/>
<Text style={{ fontSize: 20 }}>{this.props.facebookToken}</Text>
</View>
);
}
}
function mapStateToProps(state) {
return {
facebookToken: state.facebookToken
}
}
export default connect(mapStateToProps, null)(VerifyScreen)
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
In my LoginScreen, when I console.log this.state.facbookToken
I get the data, but when I navigate to the nextScreen(VerifyScreen) and console.log it, I get undefined
.
My question: how could I call global state from the VerifyScreen? I am very new to redux so I might be doing things wrong. Any advise or comments would really help. Thanks in advance!
In your verify screen, you try to console log this.state.facebookToken which definitely undefined. Instead try to update the code to this.props.facebookToken
console.log(this.props.facebookToken,'this.props.facebookToken')}/>
this.state
is meant to hold component level state, when you talk about global state, redux state are sitting in this.props.xxx
depending on the mapStateToProps
method you defined
UPDATES:
The problems that you're violating is,
You're not passing payload to reducer when you dispatch action
increaseCounter: ()=>dispatch({ type: 'UPDATE', payload: state.facebookToken })
Then in your App.js
, you have the following code
switch (action.type) {
case 'UPDATE':
return { facebookToken: state.facebookToken}
}
If you look at the code above, u can notice that Redux's flow work like this, we try to dispatch an action
, which is an action object with two property, type
and payload
(payload is optional, or u can name it whatever you like), then in your reducer, you can access the payload
as below
switch (action.type) {
case 'UPDATE':
return { facebookToken: action.payload };
}
you might be wondering what is action.payload
, which we provide the value when we dispatch earlier dispatch({ type: 'UPDATE', payload: state.facebookToken })
, so action.payload
simply is state.facebookToken
Extra:
Depending on your use case of course, but typically when we return a state in reducer, we would want to return all the other states, and only update the particular states that is changed, for example as below:
console.log(action);
switch (action.type) {
case 'UPDATE':
return { ...state, facebookToken: state.facebookToken };
}
Often when I'm trying to debug the problem with Redux, I will do a console.log
before the switch
statement to find out what are the type i'm dispatching, and the payload I'm passing, and hence console.log(action)
which you will be able to see the type
property, and the value of payload
property
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With