如何在React中使用Google Analytics?

9

在我的react应用程序中,我有一些页面:

  1. 主页
  2. 服务
  3. 联系我们
  4. 个人资料(私人)
  5. 等等。

我需要使用Google Analytics跟踪用户的活动。我搜索了react-ga,这个库很好用。但是,我必须在使用每个路由时初始化我的GA。例如:

路由“ / ”-主页:

class Main extends Component {

    componentDidMount() {
        initGA();
    }

    render() {
        return (
            <div>
                <Component1 />
                <Component2 />
            </div>
        )
    }
}

我的initGA()看起来像这样:

import ReactGA from 'react-ga';

export const initGA = () => {
    ReactGA.initialize('UA-00000000-1');
    ReactGA.pageview(window.location.pathname + window.location.search);
    console.log(window.location.pathname + window.location.search);
}

我的 App 类 看起来像这样:

class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <div className="App">

                    <Switch>
                        <Route exact path="/" component={Main} />
                        <Route exact path="/signup" component={SignupLayout} />
                        <Route component={PublicLayout} />
                    </Switch>

                </div>
            </BrowserRouter>
        );
    }
}

在我的使用方式中,每当路由响应时,我都会在每个组件上添加initGA()函数来使用react-ga。我认为在每个组件中重复initGA()并不正确。请问大家如何使用react-ga?使用react-ga的正确方法是什么?

7个回答

13

这是使用钩子的方法。

App.js

import React, { useEffect } from 'react'
import { Router, Route } from 'react-router-dom'
import { createBrowserHistory } from 'history'
import ReactGA from 'react-ga'

ReactGA.initialize(process.env.REACT_APP_GA_TRACKING_NO)
const browserHistory = createBrowserHistory()
browserHistory.listen((location, action) => {
  ReactGA.pageview(location.pathname + location.search)
})

const App = () => {
  useEffect(() => {
    ReactGA.pageview(window.location.pathname + window.location.search)
  }, [])

  return <div>Test</div>
}

以上使用类组件的答案基本上没问题,但是在分析中您看不到第一页加载。当路由更改时,history.listen将触发。但是,当您首次加载页面时,这种情况不会发生。为了解决这个问题,我在App组件中添加了一个useEffect钩子。如果用户重新加载站点,则App将始终重新渲染。ReactGA.pageview(window.location.pathname + window.location.search)确保我们将重载归因于正确的路线(如果路线不是'/')。


你确定这个能正常工作吗?看起来 useEffect 只会被调用一次! - Hafiz Temuri
1
它只需要被调用一次。钩子仅记录第一次页面加载。其余的页面加载将在browserHistory.listen事件监听器中记录。 - slinden
1
我使用了你的解决方案,对我非常有效。谢谢。+1 - Hafiz Temuri

11

为了使它工作,需要使用 Router 功能。所以在 App 组件中引入 import { Router } from 'react-router-dom'。必须使用 Router 而不是 BrowserRouter。

然后,引入 import createHistory from 'history/createBrowserHistory'

const history = createHistory()
ReactGA.initialize('UA-000000-1');
history.listen((location, action) => {
    ReactGA.pageview(location.pathname + location.search);
    console.log(location.pathname)
});

这段代码将在每次路由变化时执行!

然后给你的Router组件添加一个history属性。

完整代码:

import React, { Component } from 'react';
import { Router, Route, Switch } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory'
import Main from './components/pages/Main';
import ReactGA from 'react-ga';


const history = createHistory()
ReactGA.initialize('UA-00000000-1');
history.listen((location, action) => {
    ReactGA.pageview(location.pathname + location.search);
    console.log(location.pathname)
});

class App extends Component {

    render() {
        return (

            <Router history={history}>
                <div className="App">

                    <Switch>
                        <Route exact path="/" component={Main} />
                        <Route exact path="/signup" component={SignupLayout} />
                        <Route component={PublicLayout} />
                    </Switch>

                </div>
            </Router>
        );
    }
}

export default App;

那么使用这个,我们就不需要在componentDidMount() / componentWillMount()中为每个组件调用initGA()了吗? - Reema Parakh
5
这个回答没问题,但是你无法在分析中记录第一页的加载。history.listen只会在路由改变时触发,而在首次加载页面时不会发生这种情况。 - slinden
如果你不需要创建类,请使用函数式组件。我个人非常喜欢使用class,但只有在需要时才会使用它。 - Hafiz Temuri
1
@slinden 的评论可能已经过时,但也许可以帮助其他人:要注册第一页的加载,只需在 ReactGA.initialize 后立即启动 ReactGA.pageview 函数,就这样。 - tmatyo

5
这里是一个利用React Router V5.1发布的useLocation()解决方案。
这种方法的好处是,如果您希望继续使用BrowserRouter,它是兼容的。
import React, { useEffect } from 'react';
import { useLocation,} from 'react-router-dom';
import ReactGA from 'react-ga';

// Init Google Analytics
ReactGA.initialize('UA-00000000-1');

const App = () => {
  const location = useLocation();

  // Fired on every route change
  useEffect(() => {
    ReactGA.pageview(location.pathname + location.search);
  }, [location]);

  return (
    <div className="App"></div>
  )
}

1
这是目前最简单且全面可行的实现方式,谢谢! - dgamboa

1

你说的“在你的路由中”是什么意思?能否提供更详细的带有代码的示例? - Nastro
以这种方式跟踪无法工作。会出现警告:react-ga.js:88 [react-ga] 必须先调用ReactGA.initialize或手动加载GoogleAnalytics。 - Nastro
1
我在index.js中添加了ReactGA.initialize,并在每个页面上添加了ReactGA.pageview('...'),但控制台上始终会出现警告信息“必须先调用ReactGA.initialize或手动加载GoogleAnalytics”。因此,我决定在每个页面上都添加ReactGA.initialize - Rolly

1
你可以使用service.js文件解决这个问题,其中你需要进行多次输出。
import ReactGA from 'react-ga';

export const GAInit = (TrackingID) => {
   ReactGA.initialize(TrackingID)
}

export const GAEvent = (category, action) => {
ReactGA.initialize('TrackingIDHere')   
ReactGA.event({
   category,
   action
})
}

// export pageview and more...

导入App.js并初始化和使用服务,您不需要每次都进行初始化。

或者您可以使用脚本而不是react-ga来解决此问题。


0

以下是避免在每个组件上“初始化” GA 的解决方法。

基本上,确保运行的第一个 ReactGA 脚本是 ReactGA.initialize('UA-00000000-1');

为了确保这一点,您应将您的 initGA(); 放在 componentDidMount() 之外,并将其余的 ReactGA 脚本放在 componentDidMount() 内。

我知道这是一个旧帖子,但所有的答案都是关于路由跟踪而不是实际问题。


0

在我意识到我使用的是 HashRouter 之前,我一直无法获取路径(始终是 '/')。如果是这种情况,您可以应用以下方法:

import React, { useState, useEffect } from 'react';
import { Route, Switch, NavLink, HashRouter as Router } from 'react-router-dom';
import ReactGA from 'react-ga';
import { createHashHistory } from 'history';

const App = () => {
   ReactGA.initialize(trackingId);
   const browserHistory = createHashHistory();
   browserHistory.listen((location, action) => {
      ReactGA.pageview(location.pathname + location.search);
})

// Activate Google Analytics
useEffect(() => {
    ReactGA.pageview(window.location.pathname + window.location.search);
}, []);
}

顺带一提,不推荐将Google Analytics的tracking_id放在客户端上。以下是更安全的更新代码,使用axios从服务器检索tracking_id:

    useEffect(() => {
        const getTrackingID = async () => {
            await axios.get(`${url}/ga/tracking_id`, {
               headers: { 'Content-Type': 'application/json' }
            })
            .then(res => {
                if (res.status === 204) {
                    console.log('No GA tracking_id found');
                } else if (res.status === 200) {
                    const trackingId = res.data;
                    ReactGA.initialize(trackingId);
                    // Capture 1st load in home page
                    ReactGA.pageview(window.location.pathname + window.location.search);
                    // Capture any subsequent page change
                    browserHistory.listen((location) => {
                        ReactGA.pageview(location.pathname + location.search);
                    });
                }
            })
            .catch(err => {
                console.log('Error while retrieving GA tracking_id', err);
            });
       };
       getTrackingID();
   }, []);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接