0

I am doing a simple react application and I have an App component which keeps track of the state and then renders it. At first the state it is an empty string. Afterwards when I access the /signin I click on a button that changes the state from "" to "Marc" and pass it via props to the Profile component who renders the name of the user on its page. The problem is that it does not change the state and it is always "". I tried to debug and the state is always "" but the method setState is actually called. So i do not know why. Can anyone help me? Thanks in advance and I enclose the code.

APP:

export default class App extends React.Component {

    constructor(props) {
        super(props);
            this.state = {
            session: ""
        };
        this.updateUser = this.updateUser.bind(this);
    }

    updateUser() {
        this.setState({
            session: "Marc"
        });
    }

render() {
    return(
        <BrowserRouter>
            <Switch>
                <Route path exact='/' component={Home}/>
                <Route path='/profile' render={(props) => (
                    <Profile session={this.state.session} /> 
                )}/>                                            
                <Route path='/signin' render={(props) => (
                    <SignIn onClick={this.updateUser} />
                )}/> 
            </Switch>    
        </BrowserRouter>
    );
}

}

SIGNIN:

export default class SignIn extends React.Component{

constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
}


responseGoogle (googleUser) {
    const mail = googleUser.profileObj.email;
    const familyName = googleUser.profileObj.familyName;
    const name = googleUser.profileObj.name;
    //this.changeName(mail);
    alert("Mail: " + mail + "\n" + "Nom i Cognoms: " + name + "\nSuccessfully Logged In");
}

handleClick() {
    this.props.onClick();
}

render () {
    return (
    <div>
        <GoogleLogin 
                    clientId="CLIENTID"
                    onSuccess={this.responseGoogle}
                    onFailure={this.responseGoogle}
                    buttonText="Google"/>
        <button onClick={this.handleClick}>Instant User</button>            
    </div>
    );
}

}

PROFILE:

export default class Profile extends React.Component {

constructor(props) {
    super(props)
}


render() {
    return(
        <h1>I am {this.props.session} User</h1>
    );
}
}
Sailendra
  • 1,318
  • 14
  • 29
marc1161
  • 25
  • 9
  • Profile component will show the props only when you change the route, which I don't see you changing. Also do you see some error in console – Shubham Khatri Jul 18 '17 at 09:02
  • No I don't see any error in the console. So how could I do if I want the profile page to change the user when I click on the button on the Sign In page? – marc1161 Jul 18 '17 at 09:06
  • see this https://stackoverflow.com/questions/44127739/programatically-routing-based-on-a-condition-with-react-router/44128108#44128108 – Shubham Khatri Jul 18 '17 at 09:07
  • But I just want to change the state of the App parent. And then if i go to /profile just see the update. Isn't it possible? – marc1161 Jul 18 '17 at 09:13
  • yes , it is and it should work as long as you are navigating through link and not refreshing the page with the profile url since local state change is lost – Shubham Khatri Jul 18 '17 at 09:14
  • Okay now I get it, but how could I redirect from the button to /profile when it is clicked? Because as I understood, if I update the state when I click the button and in the same place I redirect it to /profile, the state should be updated? – marc1161 Jul 18 '17 at 09:20
  • In order to dynamically route you should follow the link I posted in my comments earlier, else you could have a Link component that changes route to Profile – Shubham Khatri Jul 18 '17 at 09:21
  • Okay I understand you, but how would you implement that? As I am new in React and it is hard to me to implement it. Sorry – marc1161 Jul 18 '17 at 09:23

1 Answers1

0

In your case when at the SignIn component, onClicking the button will update the State correctly, but when you try to visit another page say Profile by manually entering the URL in browser, your state change will be lost and the state will be reinitialized as you session has changed.

You should instead try to navigate Programatically , for which you could refer the following answer on StackOverflow:

Programatically Routing based on a condition with react-router

In short In SignIn component you will have

class SignIn extends React.Component {
     ...
    handleClick() {
        this.props.onClick();
        this.props.history.push('/profile');
    }
    ...
export default withRouter(SignIn);

The above is what I will recommend you to do, or else for testing you can have a Link component and navigate using that

render() {
    return(
        <BrowserRouter>

            <div>
            <Link to="/profile">Profile</Link>
            <Switch>
                <Route path exact='/' component={Home}/>
                <Route path='/profile' render={(props) => (
                    <Profile session={this.state.session} /> 
                )}/>                                            
                <Route path='/signin' render={(props) => (
                    <SignIn onClick={this.updateUser} />
                )}/> 
            </Switch>  
            </div>  
        </BrowserRouter>
    );
}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • thanks a lot! But why do you export withRouter(SignIn)? – marc1161 Jul 18 '17 at 09:37
  • When you want to make use of router props like history you need to wrap your component with withRouter and hence I have that statement – Shubham Khatri Jul 18 '17 at 09:38
  • Perfect! And in my case, if I wanted to do the same but instead of hardcoding the name, getting it from the Google sign in? Because my problem is that in the method responseGoogle on SignIn I can not access to this.dosomething because THIS is an instance of the google callback and not of the SignIn class.. – marc1161 Jul 18 '17 at 09:42
  • Set the state in signIn based on Google response and then send that name to the parent while setting the state in parent – Shubham Khatri Jul 18 '17 at 09:55