5

I'm building a form in React and Redux. The input for wins and losses changes the number input into a string when I type it into the form. The form isn't saving because the data type is supposed to be a number. I don't want the number to change into a string when I input it into the form.

I think the issue might be with my handleOnChange for the form.

class TeamForm extends Component {
   handleOnChange = event => {
      const { name, value } = event.target;

      const currentTeamFormData = Object.assign({}, 
      this.props.teamFormData, {
        [name]: value
        });
      this.props.updateTeamFormData(currentTeamFormData);
  };

   handleOnSubmit = event => {
       event.preventDefault();
       this.props.createTeam(this.props.teamFormData);
   };

    render() {
        const { name, wins, losses, logo_url } = this.props.teamFormData;
        return (
          <div className="teamForm">
            <h1>Add a team to the League</h1>
            <form onSubmit={this.handleOnSubmit}>
              <div>
                <label htmlFor="name">Name:</label>
                <input
                  type="text"
                  onChange={this.handleOnChange}
                  name="name"
                  value={name}
                />
              </div>
              <div>
                <label htmlFor="wins">Wins:</label>
                <input
                  type="number"
                  onChange={this.handleOnChange}
                  name="wins"
                  value={wins}
                />
              </div>
              <div>
                <label htmlFor="losses">Losses:</label>
                <input
                  type="number"
                  onChange={this.handleOnChange}
                  name="losses"
                  value={losses}
                />
              </div>
              <div>
                <label htmlFor="logo_url">Logo url:</label>
                <input
                  type="text"
                  onChange={this.handleOnChange}
                  name="logo_url"
                  value={logo_url}
                />
              </div>

              <button type="submit">Add Team</button>
            </form>
          </div>
      );
    }
}

Below is the action creator and reducer associated with updating the form.

    export const updateTeamFormData = teamFormData => {
      debugger;
      return {
        type: "UPDATED_DATA",
        teamFormData
      };
    };

    export const resetTeamForm = () => {
      return {
        type: "RESET_TEAM_FORM"
      };
    };


    const initialState = {
       name: "",
       wins: 0,
       losses: 0,
       logo_url: ""
    };

   export default (state = initialState, action) => {
      switch (action.type) {
        case "UPDATED_DATA":
          return action.teamFormData;

        case "RESET_TEAM_FORM":
          return initialState;

        default:
          return state;
      }
   };

Any help or insight is appreciated. Thanks!

2 Answers 2

8

Updates: Since it's a regular form, you can just handle this in your handleOnChange event listener:

handleOnChange = event => {
    const { name, value, type } = event.target;

    const currentTeamFormData = Object.assign({}, this.props.teamFormData, {
      [name]: type === "number" ? parseInt(value, 10) : value
    });

    this.props.updateTeamFormData(currentTeamFormData);    
};

Here I check the input.type so that handleOnChange can stay abstract/generic enough but you can use any other technique to distinguish the number type inputs (or even create separate handlers even). The idea is to see if it is a numeric type and if so, use parseInt to convert it to number.

Here's an updated sandbox (note I used setState to demo the core concepts but that's not necessary to use; you can use your redux actions as you're doing right now).

Old answer; leaving here for posterity

Redux form offers a parse function for this purpose:

<input
    type="number"
    onChange={this.handleOnChange}
    name="wins"
    value={wins}
    parse={value => parseInt(value, 10)}
/>

Note that type="number" has no effect on how the form stores the data. It is only helpful with modern browsers which can display a numeric keyboard that in turn makes your form more user friendly.

Sign up to request clarification or add additional context in comments.

4 Comments

The parse line isn't parsing the number that passes into value. Any other suggestions for this?
It does: imgur.com/a/oTge5xB. See how the stored value changes to number after adding parseInt. Here's the sandbox: codesandbox.io/s/x31n2v7r0w
I'm not using redux-form. Where do I apply parseInt to my current form input.
Well, you tagged it as redux-form! :) See my updates.
7

Input values are always sent to you as Strings, no matter the input type. When you use input type="number" it only helps the browser to present a number keypad.

You either have to cast the value to Int parseInt(myValue) before calling your action or inside the action itself.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.