使用redux全局反应本机通过状态

时间:2018-10-14 07:19:59

标签: javascript reactjs react-native redux react-redux

在我的应用程序中,LoginScreen(fristScreen)可以使用Facebook登录,并且当用户成功登录时,应用程序会收到一个Facebook access token并导航至下一个屏幕(VerifyScreen)。在VerifyScreen(secondScreen)中,当我单击一个按钮时,我要带全局状态facebookToken并显示在屏幕上。下面是我的代码:

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'
    }
});

在我的LoginScreen中,当我console.log this.state.facbookToken时,我得到了数据,但是当我导航到nextScreen(VerifyScreen)并进行console.log时,我得到了undefined

我的问题:如何从VerifyScreen调用全局状态? 我是Redux的新手,所以我可能做错了事。任何建议或评论确实有帮助。预先感谢!

1 个答案:

答案 0 :(得分:2)

在验证屏幕中,您尝试控制台记录this.state.facebookToken,该日志肯定是未定义的。而是尝试将代码更新为this.props.facebookToken

console.log(this.props.facebookToken,'this.props.facebookToken')}/>

this.state用于保持组件级状态,当您谈论全局状态时,根据您定义的this.props.xxx方法,redux状态位于mapStateToProps

更新

您违反的问题是

您在分派动作时没有将有效载荷传递给减速器

increaseCounter: ()=>dispatch({ type: 'UPDATE', payload: state.facebookToken })

然后在您的App.js中,您具有以下代码

switch (action.type) {
  case 'UPDATE':
    return { facebookToken: state.facebookToken}
}

如果您看上面的代码,您会注意到Redux的流程是这样的,我们尝试调度action,这是一个具有两个属性type和{{1 }}(有效载荷是可选的,或者您可以随意命名),然后在减速器中,您可以按以下方式访问payload

payload

您可能想知道什么是switch (action.type) { case 'UPDATE': return { facebookToken: action.payload }; } ,我们在更早分发action.payload时会提供值,所以dispatch({ type: 'UPDATE', payload: state.facebookToken })就是action.payload

额外

当然,这取决于您的用例,但是通常,当我们在reducer中返回一个状态时,我们希望返回所有其他状态,并且仅更新更改的特定状态,例如:

state.facebookToken

通常,当我尝试使用Redux调试问题时,我会在console.log(action); switch (action.type) { case 'UPDATE': return { ...state, facebookToken: state.facebookToken }; } 语句之前执行console.log,以了解我要分派的类型以及有效载荷。 m传递,因此switch,您将能够看到console.log(action)属性和type属性的值