【问题标题】:Get correct Props value from Redux从 Redux 获取正确的 Props 值
【发布时间】:2018-07-22 01:20:24
【问题描述】:

我目前正在开发一个使用 React Native 制作的登录页面,我使用 Redux 和 Thunk 作为我的中间件。我有很多关于从我的行为中获取价值的问题,当某些东西被设置时。我有一个登录页面,它在其中调用 NodeJS 服务器。单击按钮时,名为“isFetching”的值变为 true,页面应显示加载 GIF。最终完成后,它应该显示用户在触发成功登录时获得的令牌。

这是我的登录组件

Login.js

import React, { Component } from 'react'
import { TouchableHighlight, View, Text, StyleSheet, TextInput, Image } from 'react-native'

import { connect } from 'react-redux'
import { loginAPI } from '../actions/actions'

class Login extends Component {
  constructor(props){
    super(props);
  }

  render() {

    return (
      <View style={styles.container}>
        <Text>Email</Text>
      <TextInput
          placeholder="Email"
      />

      <Text>Password</Text>
      <TextInput
          placeholder="Password"
      />
        <TouchableHighlight style={styles.button} onPress={this.props.loginAPI("e@e.e", "eeee")}>
          <Text style={styles.buttonText}>Login</Text>
        </TouchableHighlight>
        {
          isFetching && <Image source={require('../images/loading_gif_src.gif')} />
        }
        {
          token ? (<Text>{token}</Text>) : null

        }
      </View>
    );
  }
}

const { token, isFetching} = this.props.user;

styles = StyleSheet.create({
  container: {
    marginTop: 100,
    paddingLeft: 20,
    paddingRight: 20
  },
  text: {
    textAlign: 'center'
  },
  button: {
    height: 60,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#0b7eff'
  },
  buttonText: {
    color: 'white'
  }
})

function mapStateToProps (state) {
  return {
    user: state.user
  }
}

function mapDispatchToProps (dispatch) {
  return {
    loginAPI: (email, password) => dispatch(loginAPI(email, password))
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Login)

现在我遇到的问题是,它一直在说我不能在我的道具上调用 undefined。

Action.js

import {
    LOGIN,
    LOGIN_SUCCESS,
    LOGIN_FAILED
} from '../constants/constants'

export function loginAPI(email, password) {
    return (dispatch) => {
        dispatch(userLogin())
        fetch("http://localhost:3000/users/login", {
                method: 'POST',
                headers: new Headers({
                    'Content-Type': 'application/json'
                  }),
                body: JSON.stringify({
                    email: email,
                    password: password,
                }) // <-- Post parameters
            })
            .then(data => data.json())
            .then(json => {
                console.log('json:', json)
                switch(json.success){
                    case true:
                        dispatch(userLoginSuccess(json.token))
                        break;
                    case false:
                        dispatch(userLoginFailed(json.message))
                    break;
                }
            })
            .catch(err => dispatch(userLoginFailed(err)))
    }
}

function userLogin() {
    return {
        type: LOGIN,
    }
}

function userLoginSuccess(token) {
    return {
        type: LOGIN_SUCCESS,
        token,
    }
}

function userLoginFailed() {
    return {
        type: LOGIN_FAILED,
    }
}

user.js(减速器)

import {
  LOGIN,
  LOGIN_SUCCESS,
  LOGIN_FAILED,
  REGISTER,
  REGISTER_SUCCESS,
  REGISTER_FAILED
  } from '../constants/constants'

const initialState = {
  token: "",
  isFetching: false,
  isRegistered: false,
  error: false
}

export default function reducers(state = initialState, action){
  switch (action.type) {
      case LOGIN:
        return {
          ...state,
          isFetching: true,
        }
      case LOGIN_SUCCESS:
        return {
          ...state,
          isFetching: false,
          token: action.token
        }
      case LOGIN_FAILED:
        return {
          ...state,
          isFetching: false,
          error: true
        }
      case REGISTER:
        return{
          ...state,
          isRegistered: false,
          error: false
        }
      case REGISTER_SUCCESS:
        return{
          ...state,
          isRegistered: true,
          error: false
        }
      case REGISTER_FAILED:
        return{
          ...state,
          isRegistered: false,
          error: true
        }  
      default:
        return state
    }
}

如何通过props正确获取token和isFetching的值?

【问题讨论】:

  • 您可能希望在Login.js 中提供isFetching 作为mapStateToProps 的道具 - 像这样:function mapStateToProps(state) { return { user: state.user, isFetching: state.isFetching }; }
  • 似乎仍然暗示它们不存在。给我一个错误,即两个值都不存在且未定义
  • 你可以尝试将Login.js的渲染函数中的这一行从isFetching &amp;&amp; &lt;Image source={require('../images/loading_gif_src.gif')} /&gt;更新为this.props.isFetching &amp;&amp; &lt;Image source={require('../images/loading_gif_src.gif')} /&gt;
  • 完美,它现在实际上正在调用 API,但没有显示它正在加载,也没有显示它收到的令牌。这是来自 thunk 的日志:pastebin.com/NZdfEesf
  • 服务器是否有可能立即以令牌响应而没有时间显示加载消息?关于显示令牌文本,我相信您必须遵循与 isFetching 相同的过程 - 提供 token 作为道具:function mapStateToProps(state) { return { token: state.token }; } 然后在渲染函数中 tokenthis.props.token

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


【解决方案1】:

提供userisFetchingtoken作为道具:

function mapStateToProps({user, isFetching, token}) {
    return { user, isFetching, token };
}

更新Login.js组件的render()方法读取props:

render() {
    const { isFetching, token } = this.props;

    return (
        <View style={styles.container}>
            <Text>Email</Text>
            <TextInput placeholder="Email" />

            <Text>Password</Text>
            <TextInput placeholder="Password" />

            <TouchableHighlight style={styles.button} onPress={this.props.loginAPI("e@e.e", "eeee")}>
                <Text style={styles.buttonText}>Login</Text>
            </TouchableHighlight>

            {
                isFetching && <Image source={require('../images/loading_gif_src.gif')} />
            }
            {
                token ? (<Text>{token}</Text>) : null
            }
        </View>
    );
}

【讨论】:

    猜你喜欢
    • 2018-05-24
    • 2019-08-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2018-05-12
    • 2019-01-15
    相关资源
    最近更新 更多