Google Analytics with react and react router - reactjs

I have been trying to integrate Google analytics in my react app and i used every way mentioned on this thread and all solutions are failing. Below are the methods i tried and the corresponding error i am getting. Hope someone can help
import React, { Fragment } from 'react';
import store from './Store';
import { Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import Navbar from './components/layout/Navbar';
import Login from './components/auth/Login';
import Footer from './components/layout/Footer';
import MobileMenu from './components/layout/MobileMenu';
import Tutorial from './components/layout/Tutorial';
import ReactGA from 'react-ga';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
ReactGA.initialize('G-11111111');
history.listen((location, action) => {
ReactGA.pageview(location.pathname + location.search);
console.log(location.pathname);
});
const App = () => {
return (
<div className="App">
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<Router history={history}>
<Fragment>
<Navbar />
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/tutorial" component={Tutorial} />
</Switch>
<MobileMenu />
<Footer />
</Fragment>
</Router>
</MuiThemeProvider>
</Provider>
</div>
);
};
export default App;
The first page loads normally but if i click on any link from my Switch i get a blank page and the following warning
react_devtools_backend.js:2450 [react-ga] path is required in .pageview()
Second method i tried with hooks i get same error
import React, { Fragment, useEffect } from 'react';
import store from './Store';
import { Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import Navbar from './components/layout/Navbar';
import Login from './components/auth/Login';
import Footer from './components/layout/Footer';
import MobileMenu from './components/layout/MobileMenu';
import Tutorial from './components/layout/Tutorial';
import ReactGA from 'react-ga';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
ReactGA.initialize('G-11111111');
history.listen((location, action) => {
ReactGA.pageview(location.pathname + location.search);
});
const App = () => {
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search);
}, []);
return (
<div className="App">
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<Router history={history}>
<Fragment>
<Navbar />
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/tutorial" component={Tutorial} />
</Switch>
<MobileMenu />
<Footer />
</Fragment>
</Router>
</MuiThemeProvider>
</Provider>
</div>
);
};
export default App;
Third way i tried using useLocation() and no history
import React, { Fragment, useEffect } from 'react';
import store from './Store';
import {
BrowserRouter as Router,
Route,
Switch,
useLocation
} from 'react-router-dom';
import { Provider } from 'react-redux';
import Navbar from './components/layout/Navbar';
import Login from './components/auth/Login';
import Footer from './components/layout/Footer';
import MobileMenu from './components/layout/MobileMenu';
import Tutorial from './components/layout/Tutorial';
import ReactGA from 'react-ga';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
ReactGA.initialize('G-11111111');
const App = () => {
const location = useLocation();
// Fired on every route change
useEffect(() => {
ReactGA.pageview(location.pathname + location.search);
}, [location]);
return (
<div className="App">
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<Router history={history}>
<Fragment>
<Navbar />
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/tutorial" component={Tutorial} />
</Switch>
<MobileMenu />
<Footer />
</Fragment>
</Router>
</MuiThemeProvider>
</Provider>
</div>
);
};
export default App;
I get the following error
TypeError: Cannot read property 'location' of undefined

Most likely it depends on whether you are using a Google Analytics 4 Property ID (G-XXXXXXXX), while the React Analytics package in question works for Universal Analytics. I suggest you create a Universal Analytics Property (as shown in following image) and use the relative identifier UA-XXXXXXX-X:

Related

React.js Routing dom#6 How do i supposed to make Routes enable in different components

I am currently struggling with Routes dom#6 in both App.js and home.js.
My App.js is below here
import Home from './components/home';
import Comments from './components/comments';
import Header from './components/header';
import Signup from './components/signup';
import Login from './components/login';
import Logout from './components/logout';
import Upload from './components/upload';
import Video_box from './components/video_box';
import { useState } from 'react';
import axios from 'axios';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import './styles/app.scss';
let sessionStorage = window.sessionStorage;
function App() {
const [ text, stateText ] = useState('');
const [ user, stateUser ] = useState({});
const loggedIn = sessionStorage.getItem('loginId');
console.log(loggedIn);
return (
<div className="App">
<Header loggedIn={loggedIn} sessionStorage={sessionStorage} />
<Routes>
<Route path="/signup" element={<Signup />} />
<Route path="/login" element={<Login sessionStorage={sessionStorage} />} />
<Route path="/logout" element={<Logout sessionStorage={sessionStorage} />} />
<Route path="/upload" element={<Upload sessionStorage={sessionStorage} />} />
<Route
path="/"
element={<Home text={text} stateText={stateText} user={user} stateUser={stateUser} />}
/>
</Routes>
</div>
);
}
export default App;
there doesn't need to focus anything except Home element.
index.js is below here:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Header from './components/header';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
// eslint-disable-next-line
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
home.js is below here
import { useRef, useEffect, useState } from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import axios from 'axios';
import Video_box from './video_box';
import Video_thumbnail from './video_thumbnail';
const Home = ({ text, stateText, user, stateUser }) => {
const [ VideoList, stateVideoList ] = useState({});
useEffect(() => {
const fetchData = async () => {
const result = await axios('/api/home');
stateVideoList(result.data[0]);
};
fetchData();
}, []);
//console.log(`/video/${VideoList._id}`);
return VideoList != {} ? (
<div className="video_container">
<Routes>
<Route
path={`/video/${VideoList._id}`}
element={
<Video_box
author={VideoList.author}
title={VideoList.title}
description={VideoList.description}
fileUrl={VideoList.fileUrl}
owner={VideoList.owner}
/>
}
/>
</Routes>
<div className="each_video_box">
<Video_thumbnail />
</div>
</div>
) : null;
};
export default Home;
I want Video_box to be rendered when moving url to '/video/xxxxx..xxx'.
If i remove the Routes and Route tag, that makes render the Video_box, but if i don't, that does't render anything.
what should i do?

Link of react-router-dom updates the URL without rendering the component

I'm using the react-router-dom Link component to manage my navigation but it doesn't work.
The Link changes the URL but doesn't render the component.
Here is a simple app describing my problem. I'm trying to use My App header as go home link:
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import React from 'react';
const Navigation = () => {
return (
<div>
<Link to="/events">
<h1>My Application</h1>
</Link>
</div>
);
};
const ConnectedNavigation = connect((state) => state)(Navigation);
export default ConnectedNavigation;
App.jsx code :
import React from 'react';
import { Provider } from 'react-redux';
import { store } from '../store/index';
import ConnectedDashboard from './Dashboard';
import ConnectedEventDetails from './EventDetails';
import { Router, Route } from 'react-router-dom';
import { history } from '../store/history';
import ConnectedNavigation from './Navigation';
export const Main = () => (
<Router history={history}>
<Provider store={store}>
<div>
<ConnectedNavigation />
<Route exact path="/events" render={() => <ConnectedDashboard />} />
<Route
exact
path="/event/:id"
//match prop is necessary in order to determine which event
//we are looking for
render={({ match }) => <ConnectedEventDetails match={match} />}
/>
</div>
</Provider>
</Router>
);
As you can see i added exact on my Routes to avoid any confusions
This problem comes from this line:
import { Router, Route } from 'react-router-dom';
The correct import is :
import { BrowserRouter as Router, Route } from 'react-router-dom';

Jest Enzyme test error :Could not find "store" in the context of "Connect(App)"

I have index.js file which contains:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App'
import * as serviceWorker from './serviceWorker';
import {combineReducers,createStore,compose,applyMiddleware} from 'redux'
import {Provider} from 'react-redux'
import thunk from 'redux-thunk'
import { HashRouter } from 'react-router-dom';
import playerReducer from './store/Player/PlayerReducers'
import cardReducer from './store/Cards/cardsReducer'
import playersReducer from './store/Players/PlayersReducer'
import stylesReducer from './store/Styles/StylesReducer'
import gameReducer from './store/Game/gameReducer'
const rootReducer = combineReducers({
player: playerReducer,
cards:cardReducer,
players:playersReducer,
styles:stylesReducer,
game:gameReducer
})
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)))
ReactDOM.render(
<Provider store={store}>
<HashRouter >
<App />
</HashRouter>
</Provider>
, document.getElementById('root'));
serviceWorker.unregister();
export default store
and I have App.js file which contains:
import React, { PureComponent, Suspense } from 'react'
import {connect} from 'react-redux'
import './App.css'
import SignUp from './Register/SignUp'
import SignIn from './Register/SignIn'
import * as stylesActions from './store/Styles/StylesActions'
import Entrance from './components/Entrance/Entrance'
import Profile from './components/Profile/Profile'
import NotFound from './UI/NotFound/NotFound'
import Fallback from './UI/Fallback/Fallback'
import { Route, Switch } from 'react-router-dom'
const Lobby = React.lazy(() => import("./Lobby/Lobby"))
const Game = React.lazy(() => import('./containers/Game/Game'))
class App extends PureComponent {
render() {
return (
<div className="App"
data-test="App-component"
>
<Switch>
<Route path="/" exact render={() => (
<Suspense fallback={
<Fallback />
}>
<Entrance />
</Suspense>
)} />
<Route path="/auth/signup" exact component={SignUp}/>
<Route path="/auth/signin" exact component={SignIn}/>
<Route path="/lobby" exact render={() => (
<Suspense fallback={
<Fallback />
}>
<Lobby />
</Suspense>
)}/>
<Route path="/profile" exact component={Profile}/>
<Route path="/game" exact render={() => (
<Suspense fallback={
<Fallback />
}>
<Game />
</Suspense>
)} />
<Route component={NotFound} />
</Switch>
</div>
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onChangeMusicStatus:(arg) => dispatch(stylesActions.musicPaused(arg))
}
}
const mapStateToProps = (state) => {
return {
player: state.player,
styles:state.styles,
players:state.players
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
when I try to test it gives me this error
Could not find "store" in the context of "Connect(App)". Either wrap the root component in a or pass a custom React context provider to and the corresponding React context consumer to Connect(App) in connect options.
what version of react-redux are you using, can you post your test, if you are using a react-redux 7 you must wrap your text component with Provider:
const TestComponent = <Provider store={store}><App /></Provider>
your test code here...
also you can export only the App component (not the connected) and test it separately.

this.props.history.push is undefined in React-Router

I want to perform history.push
but it is not working.
i have used withRouter , History etc.
can anyone help me to resolve it
register=(e)=>{
e.preventDefault()
this.props.history.push('/dashboard')
}
import React from 'react';
import './App.css';
import Login from './component/login/login'
import Header from './component/header/header'
import { createBrowserHistory } from 'history';
import { Router, Route, Switch } from 'react-router-dom'
const his=createBrowserHistory()
class App extends React.Component {
render(){
return (
<Router history={his} >
<div className="App">
<Header />
<Switch>
<Route path="/register" component={Login} exact/>
</Switch>
</div>
</Router>
);
}
}
export default App;

Cannot import const React Redux

Not sure what is going on. I am literally following a tutorial step-by-step. Below are my files. However I have added 'export' before 'const App' since I was getting errors: 'App' is declared but its value is never read. And the export seems to cause the warning to go away. But upon running the code, regardless if the export is there or not I receive the same message when I yarn start:
'/src/index.js
Attempted import error: './containers/app' does not contain a default export (imported as 'App').'
src/containers/app/index.js:
import React from 'react';
import { Route, Link } from 'react-router-dom'
import Home from '../home'
import About from '../about'
export const App = () => (
<div>
<header>
<Link to="/">Home</Link>
<Link to="/about-us">About</Link>
</header>
<main>
<Route exact path="/" component={Home} />
<Route exact path="/about-us" component={About} />
</main>
</div>
)
index.js:
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { ConnectedRouter } from "connected-react-router";
import store, { history } from "./store";
import App from "./containers/app";
import "./index.css";
const target = document.querySelector("#root");
render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<App />
</div>
</ConnectedRouter>
</Provider>,
target
);
You're exporting your App component as a named export, but trying to import it as a default import. if you add brackets to the App in your import statement, as I've demonstrated below, it should all work.
index.js
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { ConnectedRouter } from "connected-react-router";
import store, { history } from "./store";
-> add brackets here import { App } from "./containers/app"; <--
import "./index.css";
const target = document.querySelector("#root");
render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<App />
</div>
</ConnectedRouter>
</Provider>,
target
);
Alternatively, if you want to use a default export (which I think is what you were originally trying to do), you need to add a default export to the end of your App.js.
import React from 'react';
import { Route, Link } from 'react-router-dom'
import Home from '../home'
import About from '../about'
const App = () => (
<div>
<header>
<Link to="/">Home</Link>
<Link to="/about-us">About</Link>
</header>
<main>
<Route exact path="/" component={Home} />
<Route exact path="/about-us" component={About} />
</main>
</div>
)
export default App
The problem is what the error says. It's expected that App is default export:
import App from "./containers/app";
But App is named export:
export const App = () => (
...
)
If it's supposed to be used as default export, it should be exported as:
export default () => (
...
)
class App extends Component {
render() {
return (
<div>
<header>
<Link to="/">Home</Link>
<Link to="/about-us">About</Link>
</header>
<main>
<Route exact path="/" component={Home} />
<Route exact path="/about-us" component={About} />
</main>
</div>
)
export default App;

Resources