Mellisa
Mellisa

Reputation: 605

Form submission using react without having state

I have this simple scenario. User click on an edit button, he go to a page with form filled on every fields. He change something and click save, very simple. In jquery we just bind and get the values from the DOM, in angularjs 2 way binding works the same, but how about in react?

I often seeing people get the form value by binding the input to onChange, but in the edit case, the user might not touch every fields. I don't think state is needed. I need to bind my data

var item = {
    "name":"James",
    "dates": {
    "contract": [
          {"id":1,"name":"1 month","value":false},
          {"id":2,"name":"2 months","value":true}
        ]
    }}

https://jsfiddle.net/p1pztpcw/

I have one more problem. I got warning of Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option>.

Upvotes: 2

Views: 6810

Answers (3)

Facundo La Rocca
Facundo La Rocca

Reputation: 3866

Using refs you can access to input fields, and for select you have to handle when it changes. You don't need to handle everything, and even if you were using Redux you could not modify the state, so you could not have a handle event and call to this.setState(...);

Basically you can access to the value directly using this.refs.refName.value or you can use a function to set the value like this ref={(input) => { this.input = input; }} and then access it via this.input.

You can read the full docs here.

For default value on select, according to ReactJS docs using value={this.state.value} is OK. If you are getting a warning it could be caused by other reason.

In the case you were using frameworks like Redux, where you cant (or you should not) modify the state, you should dispatch an action on handleChange instead of setting the state.

But If you dont want to use handlres neither refs, then you should think to move from ReactJS. I prefer using refs because It feels cleaner.

Here you have a working example:

var Hello = React.createClass({
  handleSave: function(){
    alert('name: ' + this.refs.input.value)
    alert('selectValue: ' + this.state.selectValue)
  },
  render: function() {
    var item = {
    "name":"James",
    "dates": {
    "contract": [
          {"id":1,"name":"1 month","value":false},
          {"id":2,"name":"2 months","value":true}
        ]
    }}

    return (
      <div>
        <input type="text" value={item.name} ref={'input'}/>

        <select className="form-control" onChange={this.handleChange.bind(this)} >
          {item.dates.contract.map(obj => 
            <option value={obj.id}  selected={obj.value}>{obj.name}</option>
          )}
        </select>
    <button onClick={this.handleSave.bind(this)}>Save form</button></div>)
  },
  handleChange:function(e){
    this.setState({selectValue: e.target.value});
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

JQuery

Using JQuery is not recommended by ReactJS Team because JQuery takes away the control of the DOM from ReactJS at all, that could derive in undesirable behavior. It is suposed that we have chosen ReactJS to control the DOM for us. And really there is no need to use JQuery at all.

Upvotes: 0

Mr.Noob
Mr.Noob

Reputation: 358

The best solution is to use on change and call the single function. And you can use a switch statement if you want inside that function.

Regarding the warning: use

<select value={obj.id}>

instead of specifying it in

<option selected="true">

Upvotes: 0

Damien Leroux
Damien Leroux

Reputation: 11693

For you problem with <select>, React is able to read the props value on <select>. As a result, using selected on option with React is deprecated.

For your problem about creating a state or not, you can avoid it by, when submitting the form, reading each of the inputs value. Each input can be accessed using React ref propertie. But you'll have to bind each of the inputs:

<input type="text" ref={(input) => { this.textInput = input; }} />

Upvotes: 1

Related Questions