How do i update state when something it input into an input field?

I have a function that can convert a number into a roman numeral string. I’ve had trouble figuring out how I can update my state with the number that is entered into the input field.
I want to use the state in my ConvertIt function and finally, return something in render with output once the submit button has been hit. For now, I just need a little direction with the state.

my pen

First of all, you need to make it a controlled input, so you need to pull that value off state:

  <input
    type="number"
    name="number"
    value={ this.state.input }
  />

Then you need to tell it how to handle a change:

  <input
    type="number"
    name="number"
    value={ this.state.input }
    onChange={ this.handleChange }
  />

Then, in your change handler, you need to get the right value off the event:

  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }

Also, I’m not sure why your this.state.input is an array - I just made that a number:

  constructor(props) {
    super(props);
    this.state = {
      input: 5
    };   
    // ...

When I do that, it works for me. If you really want that as an array, it can work, you’d just have to change how you pull that value off state and how you set it.

1 Like

Thank you that worked. I’ve set up a handleClick for my input, but it doesn’t seem to work. What do I have wrong?

I’m not really sure what you are trying to do there. You have two different things with the same handleClick. And I’m not sure what is going on inside handleClick. And there are functions defined in there that should probably be pulled out for readability. It would also be very helpful if you put more effort in organizing and formatting your code - it would make it much easier to read.

It’s really become a mess, I’m gonna work on that and maybe I’ll even figure it out while organizing everything.

I also see a lot of PascalCase in there. Generally that is reserved for classes and constructors, and in React, components. Some of these don’t seem to be any of that.

Yeah, I understand the messiness. I also know that “formatting and refactoring as you go” is a habit that can be learned. This is going to get exponentially more important as your programs go, and as you start working with other people.

Is this better? I also changed my functions to camelCase.

Yeah, that’s easier to read. I’m still not clear what you’re trying to do on the submit. If I remove the form element, things work a little better. I think it was trying to intercept the submit and handle it, but you’ve got nothing there. But I don’t use forms much, not like this, so I may be wrong. But getting rid of that gets rid of the error and your click handler is called.

How can I display this code only when the submit is clicked?

      <p>result</p>

      <div>{converter(this.state.input)}</div>

Well, there are a couple of ways to do this. One might be to have a state variable that is just your converted value:

    this.state = {
      input: 1,
      converted: '',
    };

Then in your submit, you set that:

  handleClick() {
    this.setState({ converted: converter(this.state.input) });
  }

Then you can render that text conditionally:

          {
            this.state.converted && (
              <div>
                <p>result</p>
                <div>{ this.state.converted }</div>
              </div>   
            )  
          }

And if you want, you can zero out that converted variable so it won’t show once they start making inputs again:

  handleChange(event) {
    this.setState({
      input: event.target.value,
      converted: '',
    });
  }

You could also do something similar using a boolean flag on state instead of the whole value.

1 Like

What’s the reason the min and max values for my input don’t work if a number is input manually? Do I need to manage that separately with key events?

I don’t know a simple way to do this. Off hand, if you give that input an id of “number-input”, then at the top of your JS file you could have:

window.onload = () => {
  //add event listener to prevent the default behavior
  const mouseOnlyNumberInputField = document.getElementById("number-input");
  mouseOnlyNumberInputField.addEventListener("keypress", (event) => {
    event.preventDefault();
  });
}

I don’t know if there is an easier way or a more React way to do it.

I suppose another way would be to provide some validation and disable the submit button.

If you try to convert 0 or large numbers it would crash, so I was trying to limit the range of the input between 1-4999.

I was able to figure out a way to fix this within my converter function.

Sure, that makes sense. You could pull the number in bounds, or you could log an error message to you converted stare variable and render that.

Thanks for all the help today!

1 Like

I remember the struggle of trying to wrap my head around React. It’s weird at first but eventually I makes sense and is quite powerful.

1 Like

Hey, thanks for mentioning that. I’ve haven’t struggled this much since I started on here and that’s why I decided to try something smaller before this next project.