Reputation: 9194
Pretty new to React and ES6 conventions. I am trying to call an action from within a function that is inside of a componentWillMount()
. This is resulting in an Uncaught TypeError: Cannot read property 'signoutUser' of undefined
. Not quite sure how to resolve it, tried binding this
, which did resolve the problem.
This my code in its current form:
// left_site.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { signoutUser } from '../actions/authentication';
export default function(ComposedComponent) {
class LeftSite extends Component {
constructor(props, context) {
super(props, context);
}
componentWillMount() {
var timerLeft = setInterval(timer, 1000);
function timer() {
if ((sessionStorage.getItem('timer') > 0) &&
(new Date().getTime() - sessionStorage.getItem('timer') > 5000)) {
this.props.signoutUser();
} else {
sessionStorage.setItem('timer', new Date().getTime());
}
}
}
render() {
return <ComposedComponent {...this.props} />
}
}
return connect( null, { signoutUser })(LeftSite);
}
To explain what is going on, the company wants the user to automatically be logged out if they navigate away from any of the protected routes on the domain to another domain. One idea was to create a "heartbeat" that committed the time to sessionStorage
every second so long as the user is on a protected route on the domain. The idea is if the navigate to another domain, then try to come back, if the difference in the last stored time and the current time is greater than 5000ms, it will automatically signout.
There may be a better way to do this, but I couldn't think of one that 1) didn't violate privacy or 2) wouldn't trigger the logout with a refresh, unbind
for example.
The left_site.js
is a HOC--I also have a required_login.js
HOC to reroute to the login page if someone tries to access the protected route without authentication--so my protected routes are wrapped in component={LeftSite(RequireAuth(Home))}
.
LeftSite
is running fine, however when the conditional evaluates to true
and it tries to trigger the this.props.signoutUser();
the error comes up.
Upvotes: 0
Views: 469
Reputation: 9408
Function timer
is not bound to class. When it is executed at regular interval, the execution context changes. You have to bind the function before use. Also make sure you clear the interval at proper time, or when the component unmounts. I suggest you write this way
timer = () => {
if ((sessionStorage.getItem('timer') > 0) &&
(new Date().getTime() - sessionStorage.getItem('timer') > 5000)) {
this.props.signoutUser();
} else {
sessionStorage.setItem('timer', new Date().getTime());
}
}
componentWillMount() {
this.timerLeft = setInterval(this.timer, 1000)
}
componentWillUnmount() {
clearInterval(this.timerLeft);
}
Upvotes: 1
Reputation: 815
You need to bind this
to the timer function. The easier and recommended way to do this is by defining an arrow function for your timer, like this:
export default class MyComponent extends React.Component {
componentWillMount() {
const timer = () => {
console.log(this.props); // should be defined
};
const timerLeft = setInterval(timer, 1000);
}
}
This works because with arrow functions, this
is set to the this
of the enclosing context.
Upvotes: 1