0

I have a manager class in my app that is just a regular JS class, it's purely logical with no view. I use an instance of it in several of my components. For one of it's actions I'd like it to change the route in my React based app. I know I can return something to each component and then have the component do the routing, but I'd like to know if there is a way to do it from my non-react class. Is there maybe a way to pass in the history object and push the new route to it?

Thanks for any help.

EDIT: It's more of a theoretical/methodolgy question but for example: Manager class:

class MyManagerClass {
 constructor() {
    this.data = {...some internal data};
}

doSomething(param) {
    if(this.data[param]) {
        this.data[param]();
    } else {
        //here i'd like to change the route in my react app
    }
}
}

Component:

import React, {useContext, useEffect, useRef, useState} from "react";

const MyComponent = props => {
const myManagerClass = new MyManagerClass();

useEffect(() => {
    myManagerClass.doSomething('param');
}, [props.something]);

return (
    <div>Component</div>
)
}
Shane_IL
  • 325
  • 1
  • 4
  • 16

1 Answers1

2

There are minimum 2 solutions to this

SOLUTION 1:

You can pass the history object to the action as argument from the component

class Util {

  static someAction(history) {
      history.push('/someurl');
  }
}

and call it like

const Comp = () => {
   const history = useHistory();
   const someHandler = () => {
       Util.someAction(history);
   }
   ...
}

SOLUTION 2:

Use a custom history for Router and then you can import history directly into the class file

history.js

import {createBrowserHistory}  from 'history';
export const history = createBrowserHistory();

use it for Router like

import { Router } from 'react-router-dom';
import { history } from './path/to/history';
...

return (
  <Router history={history}>{/* Routes here */}</Router>
)

and then in your Class file

import {history} from '/path/to/history';


class Util {

  static someAction() {
      history.push('/someurl');
  }
}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • 1
    Ok thanks. I think the 2nd solution is what I was looking for. I'd passed in the history object as a param but didn't like it because I was passing in the same thing from a bunch of places. – Shane_IL Jun 02 '20 at 06:10
  • Thanks. I went with answer 2 as I wanted to use history outside of React components. Just be aware that there is a bug as stated (with fix) here https://stackoverflow.com/a/63615753/13408445 – Shmuli Jul 06 '21 at 17:02