How to check if a user is logged in or not within a React component


#1

Here’s my react component

import React from 'react';

var headerContent;
var currentUser = Meteor.user();

const LoginRegister = () => (
<div>
	<a href="/login" className="navbar-link">Login  | </a> 
	<a href="/register" className="navbar-link">Register </a>	
</div>

);


if (this.currentUser) {
headerContent = 'Hi there';
}
else{
headerContent = <LoginRegister />;
}

const LoginHeader = () => (
<div>		
	<p className="navbar-text navbar-right">
		{headerContent}		
	</p>		
</div>
);

export default LoginHeader;

I need to display the username if the user is logged in. Can someone tell me what I’m doing wrong here?


#2

You need to make it reactive and do something like:

const LoginHeader = (user) => (
  <div>		
    <p className="navbar-text navbar-right">
      {user ? 'Hi there' : <LoginRegister />}		
    </p>		
  </div>
);

#3

Thanks @reoh. It worked.


#4

Hi @reoh if I want to display the username instead of “Hi there”, how do you suggest I do that? Here’s my user object.


#5

What’re you using to make it reactive?


#6

I’m not quite sure because I’m new to react and meteor. Here’s a link to my project’s GitHub Repo. It would be great if you could kindly have a look. I’m using an application architecture for Meteor called Mantra.


#7

Right, so the thing you’re using to make it reactive would be react-komposer (alternatives include the react-meteor-data package)

To make it properly reactive (Meteor.user() is a reactive data source) you need to add it to your container like so:

export const composer = ({context}, onData) => {
  const {Meteor, Collections} = context();
  
  var user = Meteor.user();

  onData(null, {user});
};

Also notice that the object that was logged to the console doesn’t actually include your Meteor.user() object meaning it’s not functioning correctly

// get the 'user' key from the first argument (which is props)
const LoginHeader = ({user}) => ( 
	<div>		
		<p className="navbar-text navbar-right">
                        // display username
			{user ? 'Hi, ' + user.username : <LoginRegister />}
		</p>		
	</div>
);

P.S. make it reactive -> update when meteor data changes


#8

What I’ve been doing lately is settings the current user as part of the context of my main App component:

https://github.com/TelescopeJS/Telescope/blob/nova/packages/nova-base-components/lib/common/App.jsx#L10

This way it’s passed down to all other components that need it. Admittedly you’re not supposed to abuse context in React, but I think that’s a fair use case.


#9

Thank you so much @reoh .


#10

Consider this


#11

Awesome @jitterbop , will do.


#12

facing the same problem of making const component reactive-
I am trying to make layout reactive which dynamically loads other components. Below is a layout code -

import React from 'react';
import UMLogin from '../login/components/UMLogin.jsx';

export const MainLayouts = ({content})=>( 
<div>
    { Meteor.userId() ? 

    <div className="main-layout col-lg-12 col-md-12 col-sm-12 col-xs-12 noPadLR">
      <div className="container-bottom col-sm-12 col-xs-12">
         {content}
      </div>
    </div> 

    : <UMLogin /> 
    }
</div>
);

And one of my router looks like

FlowRouter.route('/contactUs',{
 action: function(params, queryParams) {
    mount(MainLayouts,{
        content : (<ManageContact />),
    });
}
});

Problem Statement :- If user is logged in render content otherwise show login page i.e render login component re-actively.

If user is logged in it shows the content. And I fires a command Meteor.logout() at console, user logs out.But it does not reflects in browzer. But if I fires command Meteor.userId(), it gives null i.e user is logged out. To see the change I need to refresh the page then and then only login component renders as MainLayouts is not reactive.

Thanks in advance!