Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS - cannot read this.props.value on state object

I am just starting to learn ReactJS and I have encountered an error upon compilation of my code:

TypeError: Cannot read property 'value' of undefined

The error occurs on this line: count: this.props.value on the file counter.jsx

As you can see, I have tried to use console.log(this.props) on the render function on counter.jsx in order to validate if the props are set. They are set - so I do not know why I cannot access it in the state object in my Counter class.

Question: What am I doing wrong?

counter.jsx:

import React, { Component } from 'react';

class Counter extends Component {
    state = {
        count: this.props.value,
        tags: []
    };

    render(){
        console.log(this.props);
        return (<React.Fragment>
                    <span>{this.formatCount()}</span>
                </React.Fragment>
        );
    }

    formatCount(){
        var { count } = this.state;
        return count === 0 ? <h1>Zero</h1> : count;
    }
}
export default Counter;

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import 'bootstrap/dist/css/bootstrap.css';

import Counters from './components/counters';

ReactDOM.render(<Counters />, document.getElementById('root'));
registerServiceWorker();

counters.jsx:

import React, {Component} from 'react';
import Counter from './counter';

class Counters extends Component {
    state = {
        counters: [
        {id: 1, value: 4},
        {id: 2, value: 0},
        {id: 3, value: 0},
        {id: 4, value: 0},
        ]
    };
    render(){
        return (
            <div>
            {this.state.counters.map(counter => (<Counter key={counter.id} value={counter.value} selected={true} />))}
            </div>
        );
    }
}

export default Counters;
like image 595
eric Avatar asked Jun 08 '26 23:06

eric


2 Answers

this in this.props refers the object created by the JSX <Counter {...}/>. So to get an access of this of the instance of Counter class, you need to use constructor function.

constructor(props) {
  super(props);
  this.state = {
    count: props.value,
    tags: []
  };
}

What you have right now to create the state, is pointing to the Counter class itself, not its instances, that is why this.props is undefined. You can do the same, without constructor function, with the help of getDerivedStateFromProps method.

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

class Counter extends Component {
  state = {
    count: null,
    tags: []
  };

  static getDerivedStateFromProps(props, state) {
    return {
      count: props.value,
    }
  }

  // ...
}
like image 89
Arup Rakshit Avatar answered Jun 11 '26 13:06

Arup Rakshit


Try setting the state inside a constructor , I suspect this is broken

 constructor(props) {
   super(props);
   this.state = {
    count: props.value,
    tags: []
   }
}
like image 41
sagi Avatar answered Jun 11 '26 13:06

sagi