0

As I an New to ReactJS.

What i am doing is when i type is any field State should be update in particular field -

As This is my LoginComponet and Setting small Form -

import React, { Component } from 'react';
import '../css/style.css';


export class LoginCompoent extends Component {

constructor(props) {
    super(props);
    this.state = {
        field: {
            phone: {
                value: '',
                validations: [],
                errors: []
            },
            password: {
                value: '',
                validations: [],
                errors: []
            }
        }
    };
    this.handelChangeEvent = this.handelChangeEvent.bind(this);
}

componentDidMount() {

}

handelChangeEvent(event) {

    this.setState({
        field: {
            [event.target.id]: {
                'value': event.target.value
            }
        }
    });
}

render() {
    console.log(this.state);

    return (
        <div className="loginMainDiv" >
            <div className="">
                <input className="login_inp" placeholder="Mobile Number"
                    value={this.state.field.phone.value}
                    onChange={this.handelChangeEvent}
                    type="text" name="phone" id="phone"
                />
                <input className="login_inp" placeholder="Password"
                    value={this.state.field.password.value}
                    onChange={this.handelChangeEvent}
                    type="password" name="password" id="password"
                />
                <button className="login_btn" >Login Safely</button>
            </div>
        </div>
    );
}

}

Expected Result - on console.log(this.state);

when I type 9 in phone field -

      field: {
            phone: {
                value: '9',
                validations: [],
                errors: []
            },
            password: {
                value: '',
                validations: [],
                errors: []
            }
        }

Getting Result -

field: {
            phone: {
                value: '9'
            }
        }

I don't know why all fields are suddenly hidden when i update only phone field. ?

Because of this password is not setting in the form. ERROR - this.state.field.password is undefined ???

hardy
  • 880
  • 2
  • 13
  • 30
  • Your click handler is out of scope. inline `onClick` in reactjs is no different from `addEventListener` – Andrew Apr 24 '18 at 06:44
  • 3
    *"I don't know why all fields are suddenly hidden when i update only phone field."* React doesn't to a deep merge, only a shallow one. I.e. `field` will have exactly the value that you pass to it in `setState`. If you to preserve existing properties of `field`, see https://stackoverflow.com/q/40601834/218196, https://stackoverflow.com/a/36527439/218196 and any of https://stackoverflow.com/search?q=%5Breactjs%5D+update+nested+object . – Felix Kling Apr 24 '18 at 06:44

3 Answers3

1

Deep merging issues, as you set a name property to your input, this should work:

this.setState(prevState => ({
  field: {
    ...prevState.field,
    [event.target.name]: {
      'value': event.target.value
    }
  }
}));
Striped
  • 2,544
  • 3
  • 25
  • 31
  • Thank you for response, As you said i have made the changes then i am getting `ERROR- Uncaught TypeError: Cannot read property 'id' of null` on `this.setState( prevState => ( {} ) )` ? – hardy Apr 24 '18 at 07:40
  • I edit my answer. Use the name property of your input instead of id. – Striped Apr 24 '18 at 07:54
  • Your answer was useful I have upVoted :) Thank you But that error was remove by this mention Article in my answer please refer to that - https://stackoverflow.com/questions/49994964/getting-error-on-react-component-on-render/50017338#50017338 – hardy Apr 25 '18 at 08:24
0

In your handleChangeEvent function, you are updating the value of the field in the state:

this.setState({field: {
    [event.target.id]: {
        'value': event.target.value
    }
}})

This will obviously overwrite the existing value of the field.

In your case, I would recommend using the callback function inside the setState. Please see the docs.

For example, if you want to update the value of the phone but also you want the value of the password to remain unchanged, You could do something like this:

handleChangeEvent = (event) => {
    this.setState((prevState) => {
      return {field: {
                [event.target.id]: event.target.value,
                ...prevState.field
            }
        };
    });
}
Shishir Anshuman
  • 1,115
  • 7
  • 23
  • Thank you for response, can you please tell what `...prevState.field` will do ? in set state – hardy Apr 24 '18 at 09:34
  • That's actually a destructuring assignment operator. You can read about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment – Shishir Anshuman Apr 24 '18 at 09:37
0

As I have tried all the Above answers but facing the error.

ERROR- Uncaught TypeError: Cannot read property 'id' of null on this.setState( prevState => ( {} ) ).

The Problem was - the reference of event are not maintain in async call that's why event.target is becoming null and getting above Error.

I got the concept of event.persist() which helps to maintain all the references of the event and make the Wrapper to the browser event with async calls.

You can go to this Article Reference

hardy
  • 880
  • 2
  • 13
  • 30