0

I new to react and I'm having a hard time on how to change the title when I click the button.any help would be really appreciated.

import React, { Component } from 'react';
import './style.css';
class Layout extends Component {

    constructor() {
        super();
        this.state = {
            name:"Title",
        };
    }

    func() {
        this.setState({name: "NewTitle"});
    }

    render() {
        // setTimeout(()=>{
        //     this.setState({name: "John"});
        // },2000)

        return (
            <div className = "layout">
                <h2>{this.state.name}</h2>
                <p>{this.props.val}</p>
                <input onClick = {this.func} type = "submit" value = "Done"/><br/>
            </div>
        );
    }
}
1
  • You are missing one part, binding of func method, put this line in the constructor: this.func=this.func.bind(this), Check this fiddle. Commented Jan 28, 2018 at 16:25

2 Answers 2

3

The main part you are missing is the context this.

As this has got function scope the function you are calling i.e.,

onClick = {this.func}

has lost it's context.

So there are two ways to achieve this.

1) Using the fat arrow function

Fat arrow function has lexical scope. It passes the this context of the class into the function you declare.

class Layout extends Component {

    constructor() {
        super();
        this.state = {
            name:"Title",
        };
    }

    func = () => {
        this.setState({name: "NewTitle"});
    }

    render() {
        // setTimeout(()=>{
        //     this.setState({name: "John"});
        // },2000)

        return (
            <div className = "layout">
                <h2>{this.state.name}</h2>
                <p>{this.props.val}</p>
                <input onClick = {this.func} type = "submit" value = "Done"/><br/>
            </div>
        );
    }
}

2) Binding the context i.e., pass the this context to the function you call

class Layout extends Component {

    constructor() {
        super();
        this.func=this.func.bind(this)
        this.state = {
            name:"Title",
        };
    }

    func(){
        this.setState({name: "NewTitle"});
    }

    render() {
        // setTimeout(()=>{
        //     this.setState({name: "John"});
        // },2000)

        return (
            <div className = "layout">
                <h2>{this.state.name}</h2>
                <p>{this.props.val}</p>
                <input onClick = {this.func} type = "submit" value = "Done"/><br/>
            </div>
        );
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Commented code for better understanding

import React, { Component } from 'react';

class Layout extends Component {
  // missing props argument 
  constructor(props) {
    super(props);
    // better naming. tell the intent with the state name
    this.state = {
      title: "Default Title",
    };
  }


  updateTitle = (e) => {
    // it prevents the default behaviour of a form which is to submit
    e.preventDefault();
    // refs are probably outdated. task for you to improve it :)
    const newTitle = this.refs['wordfield'].value;
    this.setState({ title: newTitle });
    this.refs['wordfield'].value = "";
  }

  render() {
    return (
      <div className="layout">
        <h2>{this.state.title}</h2>
        <form onSubmit={this.updateTitle}>
          <p>Enter the new title</p>
          <input type='text' ref='wordfield'/>
          <button type='submit'>Start!</button>
        </form>
      </div>
    );
  }
}

export default Layout

Comments

Your Answer

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