简体   繁体   English

React-intl在Safari v8.0.8上禁用react-router的链接组件onClick事件

[英]React-intl disable react-router's Link component onClick event on Safari v8.0.8

I'm working on a react universal application who is rendered server side and client side. 我正在研究一个反应通用的应用程序,它被渲染到服务器端和客户端。 The application works #1 on Chrome, but on Safari, the react-router's Link just re-render the whole application and do an http request. 该应用程序在Chrome上运行#1,但在Safari上,react-router的Link只重新渲染整个应用程序并执行http请求。

The application render correctly, but the links don't do the transitions in Safari when it work perfectly in Chrome. 应用程序正确呈现,但是当它在Chrome中完美运行时,链接不会在Safari中进行转换。

This is my routing.js file who is an expressjs middleware 这是我的routing.js文件,它是一个expressjs中间件

    import React from 'react';
    import { trigger } from 'redial';
    import createMemoryHistory from 'history/lib/createMemoryHistory';
    import useQueries from 'history/lib/useQueries';
    import { match, RouterContext } from 'react-router';
    import { Provider } from 'react-redux';
    import { createStore, applyMiddleware } from 'redux';

    import { thunkMiddleware } from './thunkMiddleware';
    import reducers from 'reducers';
    import routes from '../routes';

    const store = applyMiddleware(thunkMiddleware)(createStore)(reducers);
    const { dispatch } = store;

    function getRootComponent(renderProps) {
      const state = store.getState();

      const component = (
        <Provider store={store}>
          <RouterContext {...renderProps} />
        </Provider>
      );

      return {
        component,
        initialState: state,
      };
    }

    function routing(req, res) {
      const history = useQueries(createMemoryHistory)();
      const location = history.createLocation(req.url);

      return new Promise((resolve, reject) => {
        match({ routes, location }, (error, redirectLocation, renderProps) => {
          // Get array of route components:
          const components = renderProps.routes.map(route => route.component);
          // Define locals to be provided to all fetcher functions:
          const locals = {
            path: renderProps.location.pathname,
            query: renderProps.location.query,
            params: renderProps.params,
            cookies: req.cookies,
            // Allow fetcher functions to dispatch Redux actions:
            dispatch,
          };

          if (typeof req.cookies.user_token === 'undefined' && (req.url !== '/login')) {
            res.status(301).redirect('/login');
          } else {
            if (redirectLocation) {
              reject(res.status(301).redirect(redirectLocation.pathname + redirectLocation.search));
            } else if (error) {
              reject(res.status(500).send(error.message));
            } else if (renderProps === null) {
              reject(res.status(404).send('Not found'));
            }

            // trigger l'action de "redial"
            trigger('fetch', components, locals)
              .then((cookieValues) => {
                let cookieTime = 3600000; // 1 heure

                if (typeof cookieValues !== 'undefined' && typeof cookieValues[0] !== 'undefined') {
                  if (typeof req.cookies.remember_me !== 'undefined') {
                    cookieTime = 1296000000; // 15 jours
                    res.cookie('remember_me', true, { maxAge: cookieTime, httpOnly: false });
                  }

                  res.cookie('user_loggedIn', cookieValues[0].user_loggedIn, { maxAge: cookieTime, httpOnly: false });
                  res.cookie('user_id', cookieValues[0].user_id, { maxAge: cookieTime, httpOnly: false });
                  res.cookie('user_token', cookieValues[0].user_token, { maxAge: cookieTime, httpOnly: false });
                }

                resolve(getRootComponent(renderProps));
              })
              .catch(reject);
          }
        });
      });
    }

    export default routing;

And this is my app.js for my client side rendering 这是我的客户端渲染的app.js

history.listen(() => {
  // Match routes based on location object:
  match({ history, routes }, (routerError, redirectLocation, renderProps) => {
    console.log(routerError, redirectLocation, renderProps);
    // Check si renderProps est true sinon c'est un redirect
    if (renderProps) {
      // Get array of route components:
      const components = renderProps.routes.map(route => route.component);

      // Define locals to be provided to all lifecycle hooks:
      const locals = {
        path: renderProps.location.pathname,
        query: renderProps.location.query,
        params: renderProps.params,
        state: store.getState(),
        // Allow lifecycle hooks to dispatch Redux actions:
        dispatch,
      };

      // Fetch deferred, client-only data dependencies
      trigger('defer', components, locals)
        // Finally, trigger 'done' lifecycle hooks:
        .then(() => {
          const state = store.getState();

          // checkIfFormIsCompleted(location, state, () => {
          renderApplication();

          trigger('done', components, { ...locals, state });
          // });
        });
    }

    function renderApplication() {
      ReactDOM.render((
        <Provider store={store}>
          <Router history={history}>{routes}</Router>
        </Provider>
      ), document.getElementById(APP_DOM_CONTAINER));
    }
  });
});

When i console.log all in both, and all was ok. 当我在两者中都安装console.log ,一切正常。 No errors, nothing wrong on the server and the client side. 没有错误,服务器和客户端没有错。 The links just don't want to trigger the history changes and do the application changes. 链接只是不想触发历史记录更改并执行应用程序更改。

I use react-router-redux too if it matter and i just updated the packages just to check if they'll work, but nothing changes. 如果重要的话,我也使用react-router-redux,我只是更新了包,只是为了检查它们是否可以工作,但没有任何变化。

"react": "^15.1.0",
"react-router": "^2.7.0",
"react-router-redux": "^4.0.0",
"redux": "^3.0.6",
"redux-form": "^5.2.4",

I just digged into the DOM to see how click events are binds and i saw that links in Safari misses the event from ReactEventListener.js . 我刚刚进入DOM,看看点击事件是如何绑定的,我看到Safari中的链接错过了ReactEventListener.js的事件。

http://imgur.com/a/GA7bI http://imgur.com/a/GA7bI

Thank you for your help! 谢谢您的帮助!

Hi had to add this polyfill script to my HTML page. 您必须将此polyfill脚本添加到我的HTML页面。

<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.fr,Intl.~locale.en" />

After, all works well! 之后,一切顺利! There was no console error or anything on my work's iMac, but on my laptop, an error was on the console. 在我的工作的iMac上没有控制台错误或任何东西,但在我的笔记本电脑上,控制台上出现了错误。

You can see more infos here: 你可以在这里看到更多信息:

http://formatjs.io/github/#polyfills http://formatjs.io/github/#polyfills

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM