Adam Lau
Adam Lau

Reputation: 183

Why does my simple name change function in React not work?

import React, { Component } from "react";
import LogIn from "./LogIn.js"
import User from "./components/User.js"

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            projectList: [],
            myProjects: [],
            userList: [],
            currentUser: "Guest"
        };

        this.logIn = this.logIn.bind(this);
        }

    logIn(name) {
        this.setState({
            currentUser : name
        })
    }    

    render() {
        return(
            <div>
                <User name = {this.state.currentUser}/>
                <LogIn logIn = {this.logIn} />
            </div>
        );
    }
}

export default App;

import React from "react";

class LogIn extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        name: ""
      };
  
      this.handleSubmit = this.handleSubmit.bind(this);
      this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleSubmit(event) {

      event.preventDefault();

      this.props.logIn(
        this.state.name
      )
      
    }
  
    handleInputChange(event) {
      const target = event.target;
      const value = target.value;
      const name = target.name;
  
      this.setState({
        [name]: value
      });
    }
  
    render() {
      return (
        <div>
            <h2> Login: </h2>
            <form onSubmit={this.handleSubmit}>
            <label>
                Name:
                <input
                name="name"
                type="textbox"
                checked={this.state.name}
                onChange={this.handleInputChange} />
            </label>
            <br />
            <input type="submit" value="Login" />
            </form>
        </div>
      );
    }
  }

export default LogIn;

import React, { Component } from "react";

class User extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name : props.name,
        }
    }

    render() {
        return (
          <div>
            <p> Current User: {this.state.name}</p>
          </div>
        )
      }
}

export default User;

Here, I have a simple App, which gives users a login form, that allows them to change their name. The User class stores the name that App passes it and renders it. However, when I submit a name in the login form, no name change is rendered. Guest is shown throughout the entire process. This leads me to believe that currentUser is not changing. Can anyone tell me why the currentUser is unchanged after logIn is called?

Upvotes: 0

Views: 536

Answers (1)

Tony Nguyen
Tony Nguyen

Reputation: 3488

In User the constructor run only one time when the component re-render. When component re-render constructor is not called, so this.state.name will not updated when component re-render. You do not need to set state for name, just render with this.props.name, the name in UI will be updated.

import React, { Component } from "react";

class User extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
          <div>
            <p> Current User: {this.props.name}</p>
          </div>
        )
      }
}

export default User;

If you really want to have state for name, you need to update the state in componentDidUpdate

import React, { Component } from "react";

class User extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name : props.name,
        }
    }
    
    componentDidUpdate(prevProps){
      if(prevProps.name !== this.props.name){
      this.setState({name: this.props.name})
    }

    render() {
        return (
          <div>
            <p> Current User: {this.state.name}</p>
          </div>
        )
      }
}

export default User;

Upvotes: 2

Related Questions