N
N
Nikita Shchypylov2018-02-07 14:29:27
React
Nikita Shchypylov, 2018-02-07 14:29:27

Why does it return undefined is not an object (evaluating 'this.props.users')?

I'm trying to get users with redux and run through them :
My component :

import React, {Component} from 'react';
import {connect} from "react-redux";
import Slider from 'material-ui/Slider';
import {addBalance} from "../actions"
import cookie from "react-cookies"
import RaisedButton from 'material-ui/RaisedButton';


class Cash extends Component {
  state = {
    cash: 0,
    user: cookie.load("userID") || "guest"
  };
  
  handleChange = (e, value) => {
    this.setState({
      cash: value*100
    });
  };
  
  submitBalance() {
    let users = this.props.users; // РУГАЕТСЯ ОН НА ЭТУ СТРОЧКУ
    let login = this.state.user;
    let value = this.state.value;
    
    if (users !== undefined) {
      Object.keys(users).map(element => {
        if (login === users[element].login) {
          this.props.addBalance(element, value)
        }
      })
    }

  }
  
  render() {
    console.log('---', this.props.users); // ТУТ СНАЧАЛА ВЫВОДИТ ПУСТОЙ ОБЪЕКТ, НО ПО ВЫПОЛНЕНИЮ ЗАПРОСУ ВОЗВРАЩАЕТ ЗНАЧЕНИЕ
    return (
        <div>
          <h1>Here you may add some money</h1>
          <span>{this.state.cash}</span>
          <Slider onChange={this.handleChange}/>
          <RaisedButton label="Primary" primary={true} onClick={this.submitBalance}/>
        </div>
    );

}
}
const mapDispatchToProps = {
addBalance
};
export default connect(state => ({cash: state.cash, users: state.users, balance: state.balance}), mapDispatchToProps)(Cash);
I even added a view check if (users !== undefined), but when submitBalance() is called, the console throws:
TypeError: undefined is not an object (evaluating 'this.props.users')

Why is this happening?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Spirin, 2018-02-07
@Nikulio

You pass a function as a callback to the onClick event listener , it loses its context and this no longer refers to your component.
You can fix it by changing the handler from class method to inline class function :

submitBalance = () => {
  // your stuff
};

or you can bind the function in the constructor:
constructor(props) {
  super(props);
  this.submitBalance.bind(this);
}

You can also wrap this.submitBalance in an arrow function in render , but this option is better to use when you need to pass your arguments:
onClick={e => this.submitBalance(someArg, e)}

R
Roman Aleksandrovich, 2018-02-07
@RomReed

try this

submitBalance() {
if (this.props!==undefined && this.props.user!==undefined){
 let users = this.props.users; // РУГАЕТСЯ ОН НА ЭТУ СТРОЧКУ
}
    
    let login = this.state.user;
    let value = this.state.value;
    
    if (users !== undefined) {
      Object.keys(users).map(element => {
        if (login === users[element].login) {
          this.props.addBalance(element, value)
        }
      })
    }

  }


render() {
    console.log('---', this.props.users); // ТУТ СНАЧАЛА ВЫВОДИТ ПУСТОЙ ОБЪЕКТ, НО ПО ВЫПОЛНЕНИЮ ЗАПРОСУ ВОЗВРАЩАЕТ ЗНАЧЕНИЕ
    return (
        <div>
          <h1>Here you may add some money</h1>
          <span>{this.state.cash}</span>
          <Slider onChange={this.handleChange}/>
          <RaisedButton label="Primary" primary={true} onClick={()=>this.submitBalance()}/>
        </div>
    );

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question