I'm trying to follow this tutorial to implement Google Analytics with pageview tracking in my React application. However, the tutorial uses a React hook, while I've set up my application using class components. I've unsuccesful to translate the tuturial to a class setting. How should I adjust to make this work for my use case?
Routes page, \src\pages\index.js:
// the function of concern
import useGaTracker from "../useGaTracker";
class Base extends Component {
render() {
useGaTracker();
// The hook inside a Class component, which is not allowed.
// But how can I make it work in my class components setting?
function withProps(Component, props) {
return function (matchProps) {
return <Component {...props} {...matchProps} />;
};
}
return (
<Router history={history}>
<Switch>
<Route exact path="/" component={Homepage} />
// Etc.
GA function, \src\useGaTracker.js:
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import ReactGA from "react-ga";
const useGaTracker = () => {
const location = useLocation();
const [initialized, setInitialized] = useState(false);
useEffect(() => {
ReactGA.initialize(process.env.REACT_APP_GA_TAG);
setInitialized(true);
}, []);
useEffect(() => {
if (initialized) {
ReactGA.pageview(window.location.pathname + window.location.search);
}
}, [initialized, location]);
};
export default useGaTracker;
And \src\index.js:
import Base from "./pages";
render(
<Provider store={store}>
<BrowserRouter>
<Base />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
Calling upon the GA function inside he Base class produces the error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
How should I rewrite this to make it work in my Class components setting?
You could make a higher-order component create a functional component, and have that one call useGaTracker
before rendering the given non-functional Component:
const withGaTracker = (Component) => {
return (props) => {
useGaTracker();
return (
<Component {...props} />
);
};
};
Then pass in the Base
component
const BaseWithGaTracker = withGaTracker(Base);
and render the result in your index.js by replacing <Base />
with <BaseWithGaTracker />
.
edit: Simpler yet, just make a single functional component that calls the hook and renders its children:
const GaTracker = ({children}) => {
useGaTracker();
return children;
}
then wrap that around <Base />
in index.js
<GaTracker>
<Base />
</GaTracker>
If you're not gonna use that hook anywhere else, you could also just inline it in the new component.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.