0

I am new to ReactJs. I am trying to achieve onClick functionality on a button to change the text between <h1> tag. Here is the code

class MessageStateComponent extends Component{

  constructor(){
    super()
    this.state = {
        message: 'Subscribe to NewsLetter'
    }
  }

  changeMessage(){

    this.setState({
        message: 'Thank You'
    })

  }

  render(){
    return (
        <div>
            <h1>{this.state.message}</h1>
            <button onClick = {this.changeMessage}>Subscribe</button>
        </div>
    )
  }

}

export default MessageStateComponent

On clicking the button I am getting this error in the console

TypeError: Cannot read property 'setState' of undefined
changeMessage src/components/MessageStateComponent.js:30
27 | 28 | changeMessage(){ 29 |

30 | this.setState({
| ^ 31 | message: 'Thank You' 32 | }) 33 |

EDIT: When I change

<button onClick = {this.changeMessage}>Subscribe</button> to
<button onClick = {this.changeMessage()}>Subscribe</button>

I am getting this error:

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

1 Answer 1

5

You need to bind the function in the constructor

constructor() {
  super()
  this.state = {
    message: 'Subscribe to NewsLetter'
  }

  this.changeMessage = this.changeMessage.bind(this)
}

If you use create-react-app it has support for class properties so you can change the function into an arrow function which will bind it automatically(because arrow functions doesn't have this context)

If you are using webpack you can add the class-properties plugin

changeMessage = () => {
  this.setState({
    message: 'Thank You'
  })
}

On the way, if you are have access to class properties through create-react-app or any other plugin, you can omit the constructor and just use class properties

class MessageStateComponent extends Component {
  state = {
    message: 'Subscribe to NewsLetter'
  }

  changeMessage = () => {
    this.setState({
      message: 'Thank You'
    })
  }

  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
        <button onClick={this.changeMessage}>Subscribe</button>
      </div>
    )
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Not all heroes wear the capes :) It worked. Thank you so much @Asaf Aviv

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.