Components can inject a session store, allowing them to access and react to changes in the user object and stored session data. These are implemented as a single React context.
Class based components can be injected with the session store using the HOC
withSession
, and accessed with this.context
.
Bedrock by default shows a loader while the session is bootstrapping. This means
that you can use withSession
and depend on the user
object to exist when the
wrapped component is mounted if the user is logged in. In most cases this is
acceptable, however if the app needs to be more responsive (ie. display non-user
specific content while bootstrapping), it can be removed (see
App.js) which will allow the wrapped component to render before the
session is loaded. For most cases, withSession
can still be used as the
wrapped component will re-render when the session is loaded. For the less common
case when components need to load data on componentDidMount
another HOC
withLoadedSession
is provided. This will wait to mount the wrapped component
until the session has been bootstrapped.
import { withSession } from 'stores/session';
class MyComponent extends React.Component {
componentDidMount() {
const { user, loading } = this.context;
console.log(user);
console.log(loading);
}
render() {
const { user } = this.context;
if (user) {
return <div>Hello {user.name}.</div>;
} else {
return 'Loading...';
}
}
}
export default withSession(MyComponent);
import { withLoadedSession } from 'stores/session';
class MyComponent extends React.Component {
// Using withLoadedSession lets you immediately take
// action with the user object on component mount
componentDidMount() {
const { user, loading } = this.context;
console.log(user); // User object when logged in
console.log(loading); // false
}
render() {
const { user } = this.context;
return <div>Hello {user.name}.</div>;
}
}
export default withLoadedSession(MyComponent);
import { withSession } from 'stores/session';
// Using the decorator pattern
@withSession
class MyComponent extends React.Component {}
Hooks allow access to the session store via the useSession
hook.
import { useSession } from 'stores/session';
export default function MyComponent() {
const { user, loading } = useSession();
if (user) {
return <div>Hello {user.name}.</div>;
} else {
return 'Loading...';
}
}
State exposed on the session context:
user
- AnObject
representing the user when loaded. Null when no authentication token is set.loading
-true
when the session is loading. This happens once on bootstrap or whenload
is explicitly called.error
- AnError
object when the session errored.stored
- AnObject
holding the locally stored data.
load()
- Reloads the session data.updateUser(data)
- Updates the user withdata
.setStored(key, value)
- Adds session data.key
must be astring
andvalue
must be serializable. Data is stored usinglocalStorage
.removeStored(key)
- Removes stored data.key
must be astring
.clearStored()
- Clears all stored data.isAdmin()
- Checks if the user has theadmin
role.hasRole(role)
- Checks if the user has a specific role.role
must be astring
.hasRoles(roles)
- Checks if the user has anyroles
.roles
must be anArray
of typestring
.authenticate(token)
- Authenticates the user.token
must be a JWT token as astring
. Returns a path to redirect.logout()
- Logs the user out. Returns a path to redirect.