2017-09-08 1 views
0

React 및 ES6 규칙에 익숙하지 않습니다. componentWillMount() 안에있는 함수 내에서 액션을 호출하려고합니다. 이로 인해 Uncaught TypeError: Cannot read property 'signoutUser' of undefined이 발생합니다. 이 문제를 해결하는 방법이 확실하지 않은 경우 this이라는 바인딩을 시도했는데 문제가 해결되었습니다.componentWillMount 내부에서 함수 내부에서 작업을 호출하면 정의되지 않은 속성을 읽을 수 없습니다.

현재의 형태로이 내 코드 :

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

는 무슨 일이 일어나고 있는지 설명하기 위해, 회사는 그들에게 도메인의 보호 경로의에서 멀리 이동하면 사용자가 자동으로 로그 아웃되고 싶어 다른 도메인. 한 가지 아이디어는 사용자가 도메인의 보호 된 경로에있는 한 1 초에 sessionStorage까지 시간을 저지른 "하트 비트"를 만드는 것이 었습니다. 아이디어는 다른 도메인으로 이동 한 다음 다시 방문하려고하는 경우입니다. 마지막으로 저장된 시간과 현재 시간의 차이가 5000ms를 초과하면 자동으로 로그 아웃됩니다.

더 좋은 방법이있을 수 있지만 1) 개인 정보 보호 정책을 위반하지 않았거나 2) 새로 고침을 사용하여 로그 아웃하지 못하도록하는 것을 생각할 수 없습니다 (예 : unbind). left_site.js

는 HOC입니다 - 그래서 내 보호 루트는 component={LeftSite(RequireAuth(Home))}에 싸여있다 - 나는 또한 누군가가 인증없이 보호 된 경로에 액세스하려고하면 로그인 페이지로 다시 라우팅 할 수있는 required_login.js HOC 있습니다.

LeftSite이 잘 실행되고 있지만 조건부 값이 true으로 계산되고 this.props.signoutUser();이 트리거되면 오류가 발생합니다.

+0

타이머 함수에'this'를 묶어야 할 수도 있습니다. https://facebook.github.io/react/docs/handling-events.html을 확인하십시오. 이벤트 처리기에 대해 이야기하지만 콜백이므로 사례에도 적용된다고 생각합니다. – Bobbyrogers

답변

1

기능 timer은 클래스에 바인딩되지 않습니다. 규칙적인 간격으로 실행되면 실행 문맥이 바뀝니다. 사용하기 전에 함수를 바인드해야합니다. 또한 적절한 시간에 또는 구성 요소가 마운트 해제 될 때 간격을 지우십시오. 이 방법을 쓰는 것이 좋습니다.

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

this을 타이머 기능에 바인딩해야합니다. 이 작업을 수행 할 수있는 쉽고 권장되는 방법은 다음과 같이 당신의 타이머 화살표 함수를 정의하는 것입니다 : 화살표 기능, this이 둘러싸고있는 컨텍스트의 this로 설정되어 있기 때문에

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

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

이 작동합니다.