2017-09-08 1 views
0

Ziemlich neu zu React und ES6 Konventionen. Ich versuche, eine Aktion innerhalb einer Funktion aufzurufen, die sich in einem componentWillMount() befindet. Dies ergibt eine Uncaught TypeError: Cannot read property 'signoutUser' of undefined. Nicht ganz sicher, wie es gelöst werden kann, versuchte verbindlich this, die das Problem gelöst hat.Aufrufen von Aktion innerhalb der Funktion innerhalb von ComponentWillMount verursacht Kann nicht lesen Eigenschaft von undefined

Das ist mein Code in seiner jetzigen 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); 
} 

Um zu erklären, was los ist, will das Unternehmen der Benutzer automatisch, wenn sie aus einem der geschützten Routen auf der Domäne entfernt navigieren abgemeldet werden eine andere Domäne. Eine Idee war es, einen "Heartbeat" zu erstellen, der die Zeit auf sessionStorage jede Sekunde festlegte, solange sich der Benutzer auf einer geschützten Route in der Domäne befindet. Die Idee ist, wenn die zu einer anderen Domäne navigieren, dann versuchen, zurück zu kommen, wenn die Differenz in der letzten gespeicherten Zeit und der aktuellen Zeit größer als 5000ms ist, wird es automatisch abmelden.

Möglicherweise gibt es eine bessere Möglichkeit, dies zu tun, aber ich konnte nicht eine, die 1) nicht verletzen Privatsphäre oder 2) würde nicht die Abmeldung mit einer Aktualisierung, zum Beispiel unbind auslösen.

Die left_site.js ist ein HOC - Ich habe auch eine required_login.js HOC zur Login-Seite zu umleiten, wenn jemand die geschützte Route ohne Authentifizierung für den Zugriff versucht - so sind meine geschützten Routen in component={LeftSite(RequireAuth(Home))} gewickelt.

LeftSite läuft gut, aber wenn die bedingte true auswertet und versucht, die this.props.signoutUser(); auszulösen, kommt der Fehler auf.

+0

Möglicherweise müssen Sie 'this' an die Timer-Funktion binden. Sehen Sie sich https://facebook.github.io/react/docs/handling-events.html an. Es spricht über Event-Handler, aber ich denke, es gilt auch für Ihren Fall, da es ein Rückruf ist – Bobbyrogers

Antwort

1

Funktion timer ist nicht an Klasse gebunden. Wenn es in regelmäßigen Abständen ausgeführt wird, ändert sich der Ausführungskontext. Sie müssen die Funktion vor der Verwendung binden. Stellen Sie außerdem sicher, dass Sie das Intervall zur richtigen Zeit löschen oder wenn die Komponente unmounten wird. Ich schlage vor, Sie auf diese Weise schreiben

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); 
} 
1

Sie müssen this an die Timer-Funktion binden. Je einfacher und empfohlene Weg, dies zu tun, ist durch einen Pfeil Funktion für Ihren Timer definiert, wie folgt aus:

export default class MyComponent extends React.Component { 
    componentWillMount() { 
    const timer =() => { 
     console.log(this.props); // should be defined 
    }; 

    const timerLeft = setInterval(timer, 1000); 
    } 
} 

Dies funktioniert, weil mit Pfeil Funktionen, this zum this des einschließenden Kontext gesetzt.

Verwandte Themen