Editable textbox in react js

Viewed 2656
class myInfo extends Component {

  constructor(props) {
    super(props);
    this.state = {
      name: sessionStorage.getItem('name'),
    };

  }

  componentDidMount() {
    axios.post('http://localhost:8080/allProfiles', {
      "name": this.state.name
    })
      .then((response) => {
        document.getElementById("email").innerHTML = "email: " + response.data.email;
      })
      .catch(function (error) {
        console.log(error);

      });
  }


  render() {
    return (
      <div>
        <p id="email"></p>
      </div>

    );
  }
}

Noob practising react here. Given the name my rest api would just return a json will all of its profile stuff like

{
    "email": ...
    "description: ...
}

For simplicity it will just get the email for now. The output of this page at the moment is

email: userFromThisSession@gmail.com

All in text. My goal is

image

Without the fancy css^^

So its the username for above image but same concept for email. I want

email: a textbox (has the email from above) (and then a button to edit it)

Anyone know how? I've been searching for a while but no luck

2 Answers

What I would do is make a component that is a simple <span> that becomes a textbox when you click on the icon:

/// inside your render() method:

(this.state.editMode)
?  <input className='edit-email' type='text' value={ this.state.email || '' } onBlur={this.toggleEditEmail} />
: <>
   <span className='edit-email' >{ this.state.email }</span>
   <img href="edit.png" onClick={this.toggleEditEmail} />
  </>

/// Toggle function:
toggleEditEmail() {
  this.setState({ editMode: !this.state.editMode });
}

You would have to then match the style of the <span> and <input> so that the input doesn't show the usual border, width, etc.

Also, note that you shouldn't need to set the HTML node directly:

document.getElementById("email").innerHTML = "email: " + response.data.email;

The React way of doing it is by setting the state:

this.setState({ email: response.data.email });

The render() I posted above will then use the email coming from this.state.

example

class Info extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    };
    this.handleChange = this.handleChange.bind(this);
    this.updateIsEdit = this.updateIsEdit.bind(this);
  }

  handleChange(e) {
    this.setState({
      name:e.target.value
    })
  }
  updateIsEdit(e, value="null") {
    this.setState({
        isEdit: value
    });
  }

  render() {
    return (
      <div>
        <input type="text" name="userName" value={this.state.name} placeholder="Enter your name..." onChange={this.handleChange} onBlur={this.updateIsEdit}/>
        <img src="https://img.icons8.com/android/24/000000/edit.png" className="edit" />
        <p id="name">{this.state.name}</p>
      </div>

    );
  }
}

render(<Info />, document.getElementById('root'));
Related