Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: window[_constants.accountListName] is undefined #18

Closed
romanown opened this issue Jul 1, 2018 · 13 comments
Closed

TypeError: window[_constants.accountListName] is undefined #18

romanown opened this issue Jul 1, 2018 · 13 comments

Comments

@romanown
Copy link

romanown commented Jul 1, 2018

if (typeof window !== 'undefined') {
is not helped
is error bellow

ymAsyncProxy
/node_modules/react-yandex-metrika/lib/index.js:41

38 | args[_key2] = arguments[_key2];
39 | }
40 |

41 | window[_constants.accountListName].forEach(function (id) {
42 | var trackerVersion = window[(0, _constants.trackerVersionName)(id)];
43 | var callbackQueue = window[(0, _constants.callbackQueueName)(trackerVersion)];
44 | if (callbackQueue) {

ym
/node_modules/react-yandex-metrika/lib/index.js:56

53 |
54 | function ym() {
55 | if (isBrowser) {

56 | ymAsyncProxy.apply(undefined, arguments);
57 | }
58 | }
59 |

./src/RoutesContainer.js/webpack_exports.a<
/src/RoutesContainer.js:67

64 | export default withRouter(props => {
65 | const isMain = props.location.pathname === '/'
66 | if (typeof window !== 'undefined') {

67 | ym('hit', props.location.pathname);
68 | }
69 |
70 | return (

@narkq
Copy link
Owner

narkq commented Jul 3, 2018

Пожалуйста, отформатируйте вывод по-нормальному.
Ну или скриншот приложите, на худой конец 🙂
Кроме того, не вижу в Вашем сообщении собственно текста ошибки.
Когда именно возникает ошибка? При сборке webpack-ом? При открытии страницы?

@romanown
Copy link
Author

romanown commented Jul 3, 2018

в момент компиляции такое. TypeError: window[_constants.accountListName] is undefined. я это из браузера скопировал что в сообщении

@romanown
Copy link
Author

romanown commented Jul 3, 2018

`TypeError: window[_constants.accountListName] is undefined
ymAsyncProxy
/node_modules/react-yandex-metrika/lib/index.js:41

args[_key2] = arguments[_key2];

}

window[_constants.accountListName].forEach(function (id) {
var trackerVersion = window[(0, _constants.trackerVersionName)(id)];
var callbackQueue = window[(0, _constants.callbackQueueName)(trackerVersion)];
if (callbackQueue) {

ym
/node_modules/react-yandex-metrika/lib/index.js:56

function ym() {
if (isBrowser) {
ymAsyncProxy.apply(undefined, arguments);
}
}

./src/RoutesContainer.js/webpack_exports.a<
D:/npm/dress/dress/src/RoutesContainer.js:70

if (typeof window !== 'undefined') { ym('hit', props.location.pathname) } `

@romanown
Copy link
Author

romanown commented Jul 3, 2018

но при переносе кода в другие места эта же ошибка выходила при попытке перехода между страницами сайта. используется серверный рендеринг.

@narkq
Copy link
Owner

narkq commented Jul 3, 2018

Я правильно понимаю, что RoutesContainer.js - это компонент роутера?
Не совсем ясно, что там за if-statement в перемешку с JSX?

Вам нужно по сути написать код, который сможет реагировать на изменения роута и посылать соответствующие события. Это ни в коем случае нельзя делать в методе render. Как правило, это делают в методе componentWillReceiveProps (вот как например в библиотеке, ссылку на которую Вы давали https://github.com/sonaye/react-with-analytics/blob/master/src/withAnalytics.js#L23 ). Впрочем, componentWillReceiveProps вроде как deprecated, так что может быть можно просто подписаться на события навигации через https://github.com/ReactTraining/history например.

@romanown
Copy link
Author

romanown commented Jul 3, 2018

наверное надо было полностью привести код как оно сейчас.
import { YMInitializer } from 'react-yandex-metrika'; import ym from 'react-yandex-metrika'; const HistoryListener = withRouter(class extends React.Component { componentDidMount() { this.props.history.listen((props) => { ym('hit', this.props.location.pathname); }) } render() { return null } }) export default withRouter(props => { return ( <div> <YMInitializer accounts={[49433788]} /> <HistoryListener /> <Switch> <Route exact path="/" component={Home} />

@narkq
Copy link
Owner

narkq commented Jul 3, 2018

Так все-таки в состоянии "как оно сейчас" работает? Или такая же ошибка?

Если такая же ошибка, то скорее всего это связано с тем, что к тому времени, как срабатывает HistoryListener.componentDidMount, не успевает отработать YMInitializer.componentDidMount (который, собственно, и создает глобальные объекты типа window[_constants.accountListName]).

Чтобы такого не происходило, можно поместить YMInitializer внутрь HistoryListener-а (т.к. метод componentDidMount вызывается в порядке, обратном иерархии компонентов). Например, так:

const HistoryListener = withRouter(
  class extends React.Component {
    historyUnlisten = null

    componentDidMount() {
      this.historyUnlisten = this.props.history.listen((location, action) => {
        ym('hit', `${location.pathname}${location.search}${location.hash}`)
      })
    }

    componentWillUnmount() {
      this.historyUnlisten()
    }

    render() {
      return <YMInitializer accounts={[49433788]} />
    }
  }
)

export default withRouter(
  props => {
    return (
      <div>
        <HistoryListener />
        <Switch>
          <Route exact path="/" component={Home} />
          ...
        </Switch>
        ...
      </div>
    )
  }
)

@narkq
Copy link
Owner

narkq commented Jul 4, 2018

ибо дидмоунт вызывается не при всех переходах

Ох. Он и не должен вызываться при всех переходах. Нужно сделать так, чтобы componentDidMount для компонентов HistoryListener и YMInitializer вызывался (желательно) ровно один раз на полную перезагрузку страницы. После этого при навигации через роутер должен вызываться только обработчик, переданный в history.listen.

@romanown
Copy link
Author

romanown commented Jul 4, 2018

теоретически так оно и есть. поскольку что-то показывается, то инициализация идет. а вот при переходе уже не срабатывает передача hit. хотя код туда доходит. я ставил алерт на каждое место.

@narkq
Copy link
Owner

narkq commented Jul 4, 2018

Какая версия react-yandex-metrika подключена?
Возможно, я кое-что сломал в 2.4.0 (или оно вообще не работало для случая, когда серверный код собирается webpack-ом).

@romanown
Copy link
Author

romanown commented Jul 4, 2018

"version": "2.3.0"

@narkq
Copy link
Owner

narkq commented Jul 4, 2018

Попробуйте поставить из вот этой ветки https://github.com/narkq/react-yandex-metrika/tree/fix-bundler-eval (например, просто удалить node_modules/react-yandex-metrika и склонировать туда эту ветку).

Вызов ym('hit') по идее нужен только в обработчике, который слушает события навигации.
При первоначальной загрузке страницы сама библиотека яндекс метрики отсылает hit (если только не указано defer: true при подключении счетчика).

@narkq narkq closed this as completed in ffe68ee Jul 4, 2018
@romanown
Copy link
Author

romanown commented Jul 5, 2018

после обновления все работает. спасибо. это единственный на данный момент найденный мною компонент модуль для react reactjs для отправки сообщения в яндекс метрику о совершенном переходе ya.metrika hit для SPA сайта. написал так чтобы другие нашли эту страницу.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants