Skip to content

Commit

Permalink
sync with remote (#2)
Browse files Browse the repository at this point in the history
* fix: jest test jsdom SecurityError

ref:  jsdom/jsdom#2304

* Add link to mobx-react-lite (mobxjs#603)

* Create a failing test for React.forwardRef

* Refs are now properly forwarded

* observer + forwardRef is now reactive

* Minor tweak, updated changelog

* Fixed weird minification issue

* Published version 5.4.0

* Fixed rollup issue, fixes mobxjs#608

* Published version 5.4.1

* Fixed issue with ForwardRef being bundled as undefined

* Published version 5.4.2

* Cleaner implementation of forwardRef

* Added open question
  • Loading branch information
noscripter authored Nov 30, 2018
1 parent 664aa60 commit d6099f3
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# MobX-React Changelog

### 5.4.1

* Fixed issue where `react-is` wasn't properly rolled-up into the package. Fixes [#608](https://github.com/mobxjs/mobx-react/issues/608)

### 5.4.0

* Added support for forward refs, fixes [#602](https://github.com/mobxjs/mobx-react/issues/602)

### 5.3.6

* Fixed some additional issues around life-cycle patching, take 3. See [#536](https://github.com/mobxjs/mobx-react/pull/586) by [@xaviergonz](https://github.com/xaviergonz). Fixed [#579](https://github.com/mobxjs/mobx-react/issues/579)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { observer } from "mobx-react/custom"
This package provides the bindings for MobX and React.
See the [official documentation](http://mobxjs.github.io/mobx/intro/overview.html) for how to get started.

If you are using [React hooks](https://reactjs.org/docs/hooks-intro.html) with latest React 16.7 and you like living on the bleeding edge then have a look at the new [mobx-react-lite](https://github.com/mobxjs/mobx-react-lite).

## Boilerplate projects that use mobx-react

* Minimal MobX, React, ES6, JSX, Hot reloading: [MobX-React-Boilerplate](https://github.com/mobxjs/mobx-react-boilerplate)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mobx-react",
"version": "5.3.6",
"version": "5.4.2",
"description": "React bindings for MobX. Create fully reactive components.",
"main": "index.js",
"jsnext:main": "index.module.js",
Expand Down
20 changes: 19 additions & 1 deletion src/observer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { Component, PureComponent } from "react"
import React, { Component, PureComponent, forwardRef } from "react"
import hoistStatics from "hoist-non-react-statics"
import { createAtom, Reaction, _allowStateChanges, $mobx } from "mobx"
import { findDOMNode as baseFindDOMNode } from "react-dom"

import EventEmitter from "./utils/EventEmitter"
import inject from "./inject"
import { patch as newPatch, newSymbol } from "./utils/utils"
Expand All @@ -25,6 +26,10 @@ export const renderReporter = new EventEmitter()
const skipRenderKey = newSymbol("skipRender")
const isForcingUpdateKey = newSymbol("isForcingUpdate")

// Using react-is had some issues (and operates on elements, not on types), see #608 / #609
const ReactForwardRefSymbol =
typeof forwardRef === "function" && forwardRef((_props, _ref) => {})["$$typeof"]

/**
* Helper to set `prop` to `this` as non-enumerable (hidden prop)
* @param target
Expand Down Expand Up @@ -318,6 +323,19 @@ export function observer(arg1, arg2) {
)
}

// Unwrap forward refs into `<Observer>` component
// we need to unwrap the render, because it is the inner render that needs to be tracked,
// not the ForwardRef HoC
if (ReactForwardRefSymbol && componentClass["$$typeof"] === ReactForwardRefSymbol) {
const baseRender = componentClass.render
if (typeof baseRender !== "function")
throw new Error("render property of ForwardRef was not a function")
// TODO: do we need to hoist statics from baseRender to the forward ref?
return forwardRef(function ObserverForwardRef() {
return <Observer>{() => baseRender.apply(undefined, arguments)}</Observer>
})
}

// Stateless function component:
// If it is function but doesn't seem to be a react class constructor,
// wrap it to a react class automatically
Expand Down
23 changes: 23 additions & 0 deletions test/__snapshots__/stateless.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`stateless component with forwardRef is reactive 1`] = `
<div>
result:
hello world
,
got ref
, a.x:
2
</div>
`;

exports[`stateless component with forwardRef render test correct 1`] = `
<div>
result:
hello world
,
got ref
, a.x:
1
</div>
`;
32 changes: 32 additions & 0 deletions test/stateless.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import TestUtils from "react-dom/test-utils"
import * as mobx from "mobx"
import { observer, propTypes } from "../src"
import { createTestRoot } from "./index"
import renderer from "react-test-renderer"
import { observable } from "mobx"

const testRoot = createTestRoot()

Expand Down Expand Up @@ -74,3 +76,33 @@ test("component with observable propTypes", () => {
expect(warnings.length).toBe(1)
console.error = originalConsoleError
})

describe("stateless component with forwardRef", () => {
const a = observable({
x: 1
})
const ForwardRefCompObserver = observer(
React.forwardRef(({ testProp }, ref) => {
return (
<div>
result: {testProp}, {ref ? "got ref" : "no ref"}, a.x: {a.x}
</div>
)
})
)

test("render test correct", () => {
const component = renderer.create(
<ForwardRefCompObserver testProp="hello world" ref={React.createRef()} />
)
expect(component).toMatchSnapshot()
})

test("is reactive", () => {
const component = renderer.create(
<ForwardRefCompObserver testProp="hello world" ref={React.createRef()} />
)
a.x++
expect(component).toMatchSnapshot()
})
})

0 comments on commit d6099f3

Please sign in to comment.