0

I am trying to update a nested state in my React login component to handle change to the login form fields.

Login Container Component

class Login extends Component {

    constructor() {

        super();

        // define state
        this.state = {
            credentials: { 'username':'', 'password':'' },
            redirect: false
        };

        // do the binding thing that React should really just do for you
        this.handleChangeField = this.handleChangeField.bind(this);
        this.httpRequest = this.httpRequest.bind(this);
        this.renderRedirect = this.renderRedirect.bind(this);
    }

    handleChangeField(e) {

        // perform coding acrobatics to update a nested state
        const credentials = {...this.state.credentials} // !!! Unexpected token error
        credentials[ e.target.name] = e.target.value;
        this.setState({credentials})
    }

    renderRedirect(){

        if(this.state.redirect) {
          return <Redirect to='/' />
        }
    }

    httpRequest(){

        const self = this;

        axios.post('/login/',this.state.credentials).then(function(res){

            if(res.data.success){ // loggedIn = true;

                self.setState({ redirect: true })
            }

        }); 
    }

    render() {

        return (    
            <div>
                {this.renderRedirect()}
                <LoginForm 
                    handleChangeField = {this.handleChangeField} 
                    httpRequest = {this.httpRequest} 
                    state = {this.state} 
                />
            </div>
        )
    }
}

Login Form Component

const LoginForm = ({handleChangeField, httpRequest, state}) => (

    <div className="login-form block-center">

        <div className="h4 mbot10">Login</div>
        <div>
            <input type="text" name="username" placeholder="username" value={state.credentials.username} onChange={handleChangeField} className="form-control" />
            <input type="text" name="password" placeholder="password" value={state.credentials.password} onChange={handleChangeField} className="form-control" />
            <button onClick={httpRequest} >Login</button>
        </div>

    </div>
)

It seems that the compiler is not recognizing the ... spread operator apparently need to update a nested state.

Many solutions Ive found use this exact syntax, what am I missing here?

Non-rhetorical side-question in the form of an editorial:

Why is it so goddamn hard to update a state for a nested object. Why would the people designing React ever assume that developers would use anything but a nested object for the state in most cases. I feel like React really needs to do a better job to support updating these kinds of operations. How about..

this.setState({credentials[e.target.name] : e.target.value})

Is that really so hard to implement?

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
yevg
  • 1,846
  • 9
  • 34
  • 70
  • Btw the binding thing is called arrow function, in case you don't want to bind the context ... – Fabien Greard Jun 20 '18 at 21:52
  • yes but then the entire component needs to be in the form of an arrow function – yevg Jun 20 '18 at 21:54
  • What do you mean by the entire component ? Because no it definetly not need arrow function everywhere inside – Fabien Greard Jun 20 '18 at 21:59
  • Your code seems to work, but here is a slightly changed version: https://codesandbox.io/s/mjq1lq0lvx You can use arrow functions wherever you want. There is no need that your entire component has to be an arrow function. Also, your state structure and managing it is not business of React, it is our job to do that. For your other questions, I think they are more to related Javascript. – devserkan Jun 20 '18 at 22:16
  • 2
    Do you have the babel plugin for spread/rest operator? You'll need that to use it: https://babeljs.io/docs/en/babel-plugin-transform-object-rest-spread/ – Jayce444 Jun 20 '18 at 22:23
  • did not know the spread operator was required a speaker plug-in - just have standard babel installed. thank you! – yevg Jun 21 '18 at 00:30

0 Answers0