最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - React Idle Timer with BrowserRouter - Stack Overflow

matteradmin4PV0评论

I'm attempting to use the React Idle Timer to go to a lock screen after 15 minutes.

The problem I am having is redirecting the page. I am using electron with react and the react BrowserRouter. Because of this I can't use window.location.assign('/clock'); (or similar window.location) method to redirect the page. Typically in my ponents I use:

this.props.history.push("/clock");

This works within the ponents that are within the Switch of the BrowserRouter. However, I need the React Idle Timer to be at the top level and when I use props.history.push inside the onIdle function I get the message:

Uncaught TypeError: Cannot read property 'push' of undefined

class AppRouter extends Component {
  constructor(props) {
    super(props);
    this.idleTimer = null;
    this.onAction = this._onAction.bind(this);
    this.onActive = this._onActive.bind(this);
    this.onIdle = this._onIdle.bind(this);
  }

  _onAction(e) {
    console.log("user did something", e);
  }

  _onActive(e) {
    console.log("user is active", e);
    console.log("time remaining", this.idleTimer.getRemainingTime());
  }

  _onIdle(e) {
    console.log("user is idle", e);
    console.log("last active", this.idleTimer.getLastActiveTime());

//need to push to  /clock after 15 minutes
//window.location.assign('/clock');  -- WORKS in browser, but not with Electron

// this.props.history.push("/clock"); -- gives Uncaught TypeError: Cannot read property 'push' of undefined

//can't place <IdleTimer inside BrowserRouter because it only allows 1 thing within.

  }

  render() {
    return (
      <div>
        <IdleTimer
          ref={ref => {
            this.idleTimer = ref;
          }}
          element={document}
          onActive={this.onActive}
          onIdle={this.onIdle}
          onAction={this.onAction}
          debounce={250}
          timeout={1000 * 60 * 0.1}
        />

        <BrowserRouter>
          <div>
            <Switch>
              <Route path="/institution" ponent={Institution} />
              <Route path="/location" ponent={Location} />
              <Route path="/timezone" ponent={TimeZone} />
              <Route path="/clock" ponent={Clock} />
              <Route path="/" ponent={PreflightCheck} />
            </Switch>
          </div>
        </BrowserRouter>
      </div>
    );
  }
}


ReactDOM.render(<AppRouter />, document.getElementById("root"));

I'm attempting to use the React Idle Timer to go to a lock screen after 15 minutes.

The problem I am having is redirecting the page. I am using electron with react and the react BrowserRouter. Because of this I can't use window.location.assign('/clock'); (or similar window.location) method to redirect the page. Typically in my ponents I use:

this.props.history.push("/clock");

This works within the ponents that are within the Switch of the BrowserRouter. However, I need the React Idle Timer to be at the top level and when I use props.history.push inside the onIdle function I get the message:

Uncaught TypeError: Cannot read property 'push' of undefined

class AppRouter extends Component {
  constructor(props) {
    super(props);
    this.idleTimer = null;
    this.onAction = this._onAction.bind(this);
    this.onActive = this._onActive.bind(this);
    this.onIdle = this._onIdle.bind(this);
  }

  _onAction(e) {
    console.log("user did something", e);
  }

  _onActive(e) {
    console.log("user is active", e);
    console.log("time remaining", this.idleTimer.getRemainingTime());
  }

  _onIdle(e) {
    console.log("user is idle", e);
    console.log("last active", this.idleTimer.getLastActiveTime());

//need to push to  /clock after 15 minutes
//window.location.assign('/clock');  -- WORKS in browser, but not with Electron

// this.props.history.push("/clock"); -- gives Uncaught TypeError: Cannot read property 'push' of undefined

//can't place <IdleTimer inside BrowserRouter because it only allows 1 thing within.

  }

  render() {
    return (
      <div>
        <IdleTimer
          ref={ref => {
            this.idleTimer = ref;
          }}
          element={document}
          onActive={this.onActive}
          onIdle={this.onIdle}
          onAction={this.onAction}
          debounce={250}
          timeout={1000 * 60 * 0.1}
        />

        <BrowserRouter>
          <div>
            <Switch>
              <Route path="/institution" ponent={Institution} />
              <Route path="/location" ponent={Location} />
              <Route path="/timezone" ponent={TimeZone} />
              <Route path="/clock" ponent={Clock} />
              <Route path="/" ponent={PreflightCheck} />
            </Switch>
          </div>
        </BrowserRouter>
      </div>
    );
  }
}


ReactDOM.render(<AppRouter />, document.getElementById("root"));

What is the correct way to redirect to a ponent at the top level outside of the BrowserRouter tags?

I have also tried this:

import { createHashHistory } from 'history'
export const history = createHashHistory()

and then calling history.push('/clock');

That only seems to append /clock to the current page that I am on and I get this message:

Hash history cannot PUSH the same path; a new entry will not be added to the history stack
Share Improve this question edited May 31, 2019 at 19:38 johnsonjp34 asked May 31, 2019 at 18:35 johnsonjp34johnsonjp34 3,2995 gold badges26 silver badges51 bronze badges 4
  • Since routes are just ponents now, maybe it makes sense to move the idle-timeout behavior into a new ponent that wraps the routes? Then you could use history.push as you usually do. – Alex Broadwin Commented May 31, 2019 at 18:41
  • You can use withRouter: reacttraining./react-router/web/api/withRouter – dahliacreative Commented May 31, 2019 at 19:04
  • Does IdleTimer not allow you to pass children? You could replace the div inside the BrowserRouter with the IdleTimer then have the switch sit inside that if so. – dahliacreative Commented May 31, 2019 at 19:05
  • The history.push continues to work fine in the other ponents. I need it to work inside the onIdle action method that is above the render area. – johnsonjp34 Commented May 31, 2019 at 19:36
Add a ment  | 

2 Answers 2

Reset to default 2

Create history (you can use npm install history):

import { createBrowserHistory } from "history";
const history = createBrowserHistory();

Then place the idle timer within Router. BrowserRouter does not seem to work with history like Router does in this situation.

<Router history={history}>
      <div>

  <IdleTimer
          ref={ref => {
            this.idleTimer = ref;
          }}
          element={document}
          onActive={this.onActive}
          onIdle={() =>  this.checkplayerstatus(history)}
          onAction={this.onAction}
          debounce={250}
          timeout={1000 * 60 * 15}
        />
        <Switch>
          <Route path="/institution" ponent={Institution} />
          <Route path="/location" ponent={Location} />
          <Route path="/timezone" ponent={TimeZone} />
          <Route path="/clock" ponent={Clock} />
          <Route path="/" ponent={PreflightCheck} />
        </Switch>
      </div>
    </>

And then in the onIdle function you can do this: "whatevervariableyoupassashistoryfromonidle".push("/clock").

   If you are using tsx means ,
      _onIdle=(e)=> {
          window.location.href = "/your_location";
       }
    or if you are using js means,
      _onIdle=(e)=> {
          window.location = "/your_location";
       }

<IdleTimer
          ref={ref => {
            this.idleTimer = ref;
          }}
           element={document}
      onActive={this.onActive}
      onIdle={this.onIdle}
      onAction={this.onAction}
          debounce={250}
          timeout={1000 * 60 * 15}  // 15 minutes
        />
Post a comment

comment list (0)

  1. No comments so far