From 8bf376737faf4695465121c9cccef831adfbdb9c Mon Sep 17 00:00:00 2001 From: Arunoda Susiripala Date: Wed, 15 Mar 2017 00:27:41 +0530 Subject: [PATCH] Remove patch-react.js (#1420) This is a pretty complex code base and it cause issues for some React components. And React/fiber is coming with a proper solution. --- client/next-dev.js | 10 ---- client/patch-react.js | 134 ------------------------------------------ 2 files changed, 144 deletions(-) delete mode 100644 client/patch-react.js diff --git a/client/next-dev.js b/client/next-dev.js index 00c1dd93..ca113212 100644 --- a/client/next-dev.js +++ b/client/next-dev.js @@ -1,18 +1,8 @@ -import patch from './patch-react' import evalScript from '../lib/eval-script' const { __NEXT_DATA__: { errorComponent } } = window const ErrorComponent = evalScript(errorComponent).default -// apply patch first -patch((err) => { - console.error(err) - - Promise.resolve().then(() => { - onError(err) - }) -}) - require('react-hot-loader/patch') const next = window.next = require('./') diff --git a/client/patch-react.js b/client/patch-react.js deleted file mode 100644 index 7a28f5db..00000000 --- a/client/patch-react.js +++ /dev/null @@ -1,134 +0,0 @@ -// monkeypatch React for fixing https://github.com/facebook/react/issues/2461 -// based on https://gist.github.com/Aldredcz/4d63b0a9049b00f54439f8780be7f0d8 - -import React from 'react' - -let patched = false - -export default (handleError = () => {}) => { - if (patched) { - throw new Error('React is already monkeypatched') - } - - patched = true - - const { createElement } = React - - React.createElement = function (Component, ...rest) { - if (typeof Component === 'function') { - // We need to get the prototype which has the render method. - // It's possible to have render inside a deeper prototype due to - // class extending. - const prototypeWithRender = getRenderPrototype(Component) - const { prototype } = Component - - // assumes it's a class component if render method exists. - const isClassComponent = Boolean(prototypeWithRender) || - // subclass of React.Component or PureComponent with no render method. - // There's no render method in prototype - // when it's created with class-properties. - prototype instanceof React.Component || - prototype instanceof React.PureComponent - - let dynamicWrapper = withWrapOwnRender - - if (isClassComponent) { - if (prototypeWithRender) { - // Sometimes render method is created with only a getter. - // In that case we can't override it with a prototype. We need to - // do it dynamically. - if (canOverrideRender(prototypeWithRender)) { - prototypeWithRender.render = wrapRender(prototypeWithRender.render) - } else { - dynamicWrapper = withWrapRenderAlways - } - } - - // wrap the render method in runtime when the component initialized - // for class-properties. - Component = wrap(Component, dynamicWrapper) - } else { - // stateless component - Component = wrapRender(Component) - } - } - - return createElement.call(this, Component, ...rest) - } - - const { Component: { prototype: componentPrototype } } = React - const { forceUpdate } = componentPrototype - - componentPrototype.forceUpdate = function (...args) { - if (this.render) { - this.render = wrapRender(this.render) - } - return forceUpdate.apply(this, args) - } - - function wrapRender (render) { - return wrap(render, withHandleError) - } - - function withHandleError (fn, ...args) { - try { - return fn.apply(this, args) - } catch (err) { - handleError(err) - return null - } - } - - function withWrapOwnRender (fn, ...args) { - const result = fn.apply(this, args) - if (this.render && this.hasOwnProperty('render')) { - this.render = wrapRender(this.render) - } - return result - } - - function withWrapRenderAlways (fn, ...args) { - const result = fn.apply(this, args) - if (this.render) { - Object.defineProperty(this, 'render', { writable: true, value: wrapRender(this.render) }) - } - return result - } -} - -function wrap (fn, around) { - if (fn.__wrapped) { - return fn.__wrapped - } - - const _fn = function (...args) { - return around.call(this, fn, ...args) - } - - for (const [k, d] of Object.entries(Object.getOwnPropertyDescriptors(fn))) { - try { - Object.defineProperty(_fn, k, d) - } catch (e) {} - } - - _fn.__wrapped = fn.__wrapped = _fn - - return _fn -} - -function getRenderPrototype (Component) { - let proto = Component.prototype - - while (true) { - if (proto.hasOwnProperty('render')) return proto - proto = Object.getPrototypeOf(proto) - if (!proto) return null - } -} - -function canOverrideRender (prototype) { - const descriptor = Object.getOwnPropertyDescriptor(prototype, 'render') - if (!descriptor) return true - - return descriptor.writable -}