William Pfaffe
William Pfaffe

Reputation: 325

Get correct Props value from Redux

I am currently working on a login page, which is made in React Native, and I use Redux and Thunk as my middleware. I have had alot of issues regarding where to get values from my actions, when something is set. I have a login page, where it makes a call to a NodeJS server. When the button is clicked, a value named "isFetching" turns to true, and the page should display a loading GIF. When finally done, it should display the token the user gets when a successful login is triggered.

This is my Login component

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("[email protected]", "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)

Now the issue that I am having, is that it's constantly saying that I cant call undefined on my props.

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 (Reducer)

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
    }
}

How can I get the value of token and isFetching properly, through props?

Upvotes: 1

Views: 1611

Answers (1)

Varinder
Varinder

Reputation: 2664

Provide user, isFetching and token as props:

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

Update render() method of Login.js component to read 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("[email protected]", "eeee")}>
                <Text style={styles.buttonText}>Login</Text>
            </TouchableHighlight>

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

Upvotes: 1

Related Questions