React- input field turns to string after onChange

react get input value
react input component
react get input value on button click
react input default value
checkbox react
react form tutorial
react label
select react

I have a small app with three components

  1. parent => App
  2. Son => Courses
  3. Grandchild => Course

The app state lies in the App component, in the Course component I have an input field with an onChange event that spouse to change the state in the app component, the problem is that every time I type the input changes to a string and I can't keep typing and changing the state.

The values arrive to the parent.

This is my Course code

import React, { Component } from 'react'

class Course extends Component {
    updatedGrade = (e) => {
        this.props.updateCourseGrade(Number(e.target.value), Number(e.target.id));

    };
    render() {
        const {id, courseType, courseName, courseGrade} = this.props.course;
        return (
            <tr key={id}>
                <td>
                    {courseName}
                </td>
                <td> 
                    {(courseType ? 'a' : 'm' )}
                </td>
                <td>
        {(courseGrade !== '' 
            ? courseGrade 
            : <input 
                type="number"
                id={id}
                onChange={this.updatedGrade}
                value={courseGrade}
            /> 
        )}
                </td>
                <td>
                    <button 
                        onClick={this.props.removeCourse.bind(this, id)}
                        style={btnStyle}
                    >
                        remove
                    </button>
                </td>
            </tr>
        )
    }
}

this is my App relevant code:

    class App extends Component {
  state = {
    courses: [
      {
        id: 1,
        courseName: 'bioliogy,
        courseType: false,
        courseHours: 10,
        courseGrade: ''
      },{
        id: 2,
        courseName: 'Mahematics,
        courseType: true,
        courseHours: 20,
        courseGrade: ''
      },{
        id: 3,
        courseName: 'History,
        courseType: false,
        courseHours: 30,
        courseGrade: 50
      }
    ]
  };



  updateCourseGrade(courseGrade, id){

    //const courseGradeNum = Number(courseGrade);
    this.setState({
      courses: this.state.courses.map(course => course.id === id ? {...course, courseGrade } : course)
    })
  console.log('courseGrade ', courseGrade);

Now, when I do this:

 updateCourseGrade(courseGrade, id){

    const courseGradeNum = Number(courseGrade);
    this.setState({
      courses: this.state.courses.map(course => course.id === id ? {...course, courseGradeNum } : course)
    })

The state will get a new value while typing named courseGrade and I don't want this. as well the courseGrade is already defined as a Number in the Course component

What can I do? maybe I shouldn't use value in the course component?

UPDATE

According to Freeman Lambda request, this is the state after I change the value in the input field, the state of courseGrade of the desired course changes. but because the input field disappears I cannot keep typing.

Link to a video that shows what happens https://www.screencast.com/t/Cyz1v6zMWsq

Here:

    {(courseGrade !== '' 
            ? courseGrade 
            : <input 
                type="number"
                id={id}
                onChange={this.updatedGrade}
                value={courseGrade}
            /> 
        )}

You explicitely change the input to a plain string a soon as courseGrade is !== ''

if you want to be able to keep typing you have to stick with an input during typing. If you want the input to disapear after typing you will have to add a button controlling a state that removes the input, for example:

class Course extends Component {
    state = {
        gradeValidated: false,
    }
    updatedGrade = (e) => {
        this.props.updateCourseGrade(Number(e.target.value), Number(e.target.id));

    };
    toggleGradeInput = (e) => {
        this.setState((state) => ({ gradeValidated: !state.gradeValidated }));

    };
    render() {
        const {id, courseType, courseName, courseGrade} = this.props.course;
        return (
            <tr key={id}>
                <td>
                    {courseName}
                </td>
                <td> 
                    {(courseType ? 'a' : 'm' )}
                </td>
                <td>
        {(this.state.gradeValidated 
            ? courseGrade 
            : <input 
                type="number"
                id={id}
                onChange={this.updatedGrade}
                value={courseGrade}
            /> 
        )}
                </td>
                <td>
                    <button 
                        onClick={this.toggleGradeInput}
                        style={btnStyle}
                    >
                        toggle input
                    </button>
                    <button 
                        onClick={this.props.removeCourse.bind(this, id)}
                        style={btnStyle}
                    >
                        remove
                    </button>
                </td>
            </tr>
        )
    }
}

[React] How to manipulate input values before storing to state., Tagged with react, forms, javascript, tutorial. What this does, is stores the value of the input field (so, whatever the user types or Our onChange is saying to run the handleInput handler, passing the event Turns out, it's quite easy. the part of the string at the index value you define, and anything after it. Specifying the value prop on a controlled component prevents the user from changing the input unless you desire so. If you’ve specified a value but the input is still editable, you may have accidentally set value to undefined or null. The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.)

The problem is here

courseGrade !== '' 
            ? courseGrade 
            : <input 
                type="number"
                id={id}
                onChange={this.updatedGrade}
                value={courseGrade}
            /> 

the first condition is set to true if you set any state instead of '', so my idea is to use a save button for the grate and onChange keep on a local state.

React- input field turns to string after onChange, The app state lies in the App component, in the Course component I have an input field with an onChange event that spouse to change the� I have a small app with three components. parent => App Son => Courses Grandchild => Course The app state lies in the App component, in the Course component I have an input field with an onChange event that spouse to change the state in the app component, the problem is that every time I type the input changes to a string and I can't keep typing and changing the state.

You should use an updater function for this, I think what is happening is that state updates are getting batched.

So instead of

this.setState({
      courses: this.state.courses.map(course => course.id === id ? {...course, courseGradeNum } : course)
    })

try

this.setState( prevState => ({
      courses: prevState.courses.map(course => course.id === id ? {...course, courseGradeNum } : course)
    }))

If this wasn't the problem can you create a code sandbox because there just isn't enough code to understand what is going on. For example, updateCourseGrade is being bound anywhere. don't know if you haven't or if you are just not showing it.

React- input field turns to string after onChange Announcing the , React- input field turns to string after onChange Announcing the arrival of Valued Associate Multi tool use. Why is it faster to reheat something� An onChange event handler returns a Synthetic Event object which contains useful meta data such as the target input’s id, name, and current value. We can access the target input’s value inside of the handleChange by accessing e.target.value. Therefore, to log the name of the input field, we can log e.target.name.

Forms – React, HTML form elements work a little bit differently from other DOM elements in React , handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this. (The input is locked at first but becomes editable after a short delay.) keeping track of the visited fields, and handling form submission, Formik is� Unlike HTML, React components must represent the state of the view at any point in time and not only at initialization time."* Basically, you can't easily rely on the input field because the state needs to come from the React app's state, not from the browser's idea of what the value should be. You might try this

Handling User Input in React — CRUD | by John Kagga, In Chapter Two, get introduced to React components. Initially, there is no text displayed in the input field because its value attribute is When the user clicks on the input field and starts typing, each keystroke triggers the onChange event handler. After all that we update the component state using this. ReactJS: Input fire onChange when user stopped typing (or pressed Enter key) - Component.jsx

React Quick Tip: Easy Data Binding with a Generic `onChange , React Quick Tip: Easy Data Binding with a Generic `onChange` Handler Initialize all text fields with empty strings. to update state whenever the text field value changes, but it becomes less suitable when more functionality� @sydcanem To the best of my understanding, onChange and onInput (theorically) occur after the fact and only notify that the input has changed (so only in a textarea will it trigger those events). onInput sounds like it should have something do with keyboard input but is just an instant version of onChange , but in React it's as far as I'm aware

Comments
  • try to use not onChange but onInput and use e.currentTarget.value instead of e.target.value
  • nope... still the same result
  • I could not clearly understand what is happening with your updateCourseGrad and what is it that you actually would want to happen there. Can you please extend the question with an example of App's state before and after updateCourseGrade is executed?
  • I have extended my question, I want to be able to type more than one digit
  • I added a link to a video that show what happend
  • If the state updater function is new to you http://joshpitzalis.com/setState