So you’re creating a thing in React where you need the user to enter some money numbers. I mean numbers representing money, like $1,234.56. But you want this to format nicely on its own while the user is typing. And you don’t want to think much about how to actually solve that problem because you’re lazy, and that’s ok; All the best programmers are lazy.

import React, { Component } from 'react';
import { connect } from 'react-redux'; // I'm using redux

class MonetaryExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      invoice: {
        fee: 0
      }
    };

    // Do all binding in the constructor, right here
    this.updateInvoicePayment = this.updateInvoicePayment.bind(this);
}

updateInvoicePayment(e) {
  let field = e.currentTarget.dataset.field;
  let value = e.currentTarget.value

  if (value !== '') {
    value = value.replace(/[^0-9]/g, ''); // remove all non-digits
    value = value.slice(0, -2) + '.' + value.slice(-2); // place the decimal
    value = parseFloat(value).toFixed(2); // now parseFloat for sanity
  }

  let invoice = this.state.invoice;
  invoice[field] = value; // this.state.invoice.fee
  this.setState({ invoice });
}

render(){

    return (<div style={{display: 'flex'}}>

      <span>$</span>

      <span>
        <input
          type="text"
          data-field={'fee'}
          value={this.state.invoice.fee}
          onChange={this.updateInvoicePayment}
        />
      </span>

    </div>);

  }

}

export default connect((state, ownProps) => ({
  user: state.user // Brings in this.props.user from the store
}), dispatch => ({
  // thing: (data) => dispatch({ type: "DO_THING_IN_SAGA", data }),
}))(MonetaryExample);

Explaination

Notice that the $ in the render is not a part of your this.state.invoice.fee variable. Because the $ doesn’t need to be in the data; the $ is for display only, right? So maybe style it and position it to make it look nicer to the left of the input field.

For me, using display:flex on the parent div is the easiest way to get the $ and the input field to line up on the same line IMO.

Save the class and load it in your browser. If you try to select your input field and press backspace, it will default to a 0. If you then type a number, you immediately go from 0 to 0.01. press another number you get 0.12, and press 3 you get 1.23. Keep pressing numbers and you may end up with a fully formatted string including commas ever 3 digits, such as 12,345.67. This is the perfect function for entering money amounts with nice, automated formatting upon input.