【问题标题】:react-native pass state globally using redux使用 redux 全局反应原生传递状态
【发布时间】:2019-03-18 22:00:22
【问题描述】:

在我的应用程序中,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 很陌生,所以我可能做错了。任何建议或 cmets 都会有帮助。提前致谢!

【问题讨论】:

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


    【解决方案1】:

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

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

    this.state 是用来保存组件级状态的,当你谈论全局状态时,redux 状态位于 this.props.xxx 取决于你定义的 mapStateToProps 方法

    更新

    你违反的问题是,

    您在调度操作时没有将有效负载传递给减速器

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

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

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

    如果你看上面的代码,你可以注意到 Redux 的流程是这样工作的,我们尝试调度一个 action,这是一个具有两个属性的动作对象,typepayload(有效载荷是可选的,或者你可以随意命名),然后在你的减速器中,你可以访问payload,如下所示

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

    您可能想知道action.payload 是什么,这是我们在之前发送dispatch({ type: 'UPDATE', payload: state.facebookToken }) 时提供的值,所以action.payload 就是state.facebookToken

    额外

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

    console.log(action);
    switch (action.type) {
      case 'UPDATE':
        return { ...state, facebookToken: state.facebookToken };
    }
    

    通常当我尝试使用 Redux 调试问题时,我会在 switch 语句之前执行 console.log 语句以找出我正在调度的类型以及我正在传递的有效负载,以及因此console.log(action),您将能够看到type 属性,以及payload 属性的值

    【讨论】:

    • 非常感谢您的评论,它真的很有帮助。但是我将代码更改为this.props.facebookToken,但仍然得到null。你知道我做错了什么吗?
    • 非常感谢您的解释。很确定你解释得很好,我想接受你的回答。但是我对redux还是有点迷茫,请你提供完整的代码,比如App.jsLoginScreen.js和'VerifyScreen.js`,这真的很有帮助。
    • 想通了!必须像function mapDispatchToProps(dispatch) { return { updateState: (state) =&gt; dispatch({ type: 'UPDATE', payload: state.facebookToken }), } } 那样定义状态,然后是onPress={() =&gt; this.props.updateState(this.state)}
    • 我将在即将到来的周末有空时与您分享snack,分享一些提高可读性的常见做法。敬请期待!
    • @kirimi:嗨,Kirimi,您可以查看github.com/isaaclem/manager/blob/master/src/components/… 以显示如何键入密码和用户名并更新 redux 状态以及单击按钮登录
    猜你喜欢
    • 1970-01-01
    • 2020-10-03
    • 2021-01-04
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2018-05-08
    相关资源
    最近更新 更多