Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

Commit

Permalink
Update to React 16.8 (#57)
Browse files Browse the repository at this point in the history
* Try update to React 16.8

* Properly update @types/react

* Update types to latest

* Fix broken forceUpdate

* Update @types properly again :/

* Fix assertEnvironment test

* Upgrade other dev dependencies

* Upgrade react-testing-library

* Fix warnings in tests

* Upgrade to React 16.8.1
  • Loading branch information
FredyC authored Feb 6, 2019
1 parent c363c9f commit 384d857
Show file tree
Hide file tree
Showing 13 changed files with 330 additions and 323 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

This is a next iteration of [mobx-react](https://github.com/mobxjs/mobx-react) coming from introducing React hooks which simplifies a lot of internal workings of this package. Class based components **are not supported** except using `<Observer>` directly in its `render` method.

**You need React version 16.7.0-alpha.2 or 16.8.0-alpha.0 which is highly experimental and not recommended for production.**

**Do not use React 16.7 as it's [missing Hooks support](https://reactjs.org/blog/2018/12/19/react-v-16-7.html)!**
**You need React version 16.8.0 and above**

[![NPM](https://nodei.co/npm/mobx-react-lite.png)](https://www.npmjs.com/package/mobx-react-lite)

Expand Down Expand Up @@ -230,7 +228,7 @@ Returns the generated disposer for early disposal.
Example (TypeScript):

```typescript
import {reaction} from 'mobx'
import { reaction } from "mobx"
import { observer, useComputed, useDisposable } from "mobx-react-lite"

const Name = observer((props: { firstName: string; lastName: string }) => {
Expand Down
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,39 @@
"homepage": "https://mobxjs.github.io/mobx",
"peerDependencies": {
"mobx": "^4.0.0 || ^5.0.0",
"react": "16.7.0-alpha.2 || 16.8.0-alpha.0"
"react": "^16.8.0"
},
"devDependencies": {
"@types/jest": "^23.3.9",
"@types/node": "^10.0.0",
"@types/react": "^16.7.2",
"@types/react-dom": "^16.0.9",
"@types/jest": "23.3.12",
"@types/node": "^10.12.21",
"@types/react": "^16.8.2",
"@types/react-dom": "^16.8.0",
"coveralls": "^3.0.2",
"husky": "^1.1.3",
"jest": "^23.6.0",
"jest-dom": "^3.0.0",
"jest-environment-jsdom": "^23.4.0",
"jest-mock-console": "^0.4.2",
"lint-staged": "^8.0.4",
"lint-staged": "^8.1.3",
"lodash": "^4.17.11",
"mobx": "^5.0.0",
"prettier": "^1.15.2",
"react": "16.8.0-alpha.0",
"react-dom": "16.8.0-alpha.0",
"react-testing-library": "^5.2.3",
"prettier": "^1.16.4",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"react-testing-library": "^5.5.3",
"rimraf": "^2.6.2",
"rollup": "^1.1.0",
"rollup": "^1.1.2",
"rollup-plugin-alias": "^1.4.0",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-filesize": "^6.0.0",
"rollup-plugin-filesize": "^6.0.1",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-terser": "^4.0.0",
"rollup-plugin-typescript2": "^0.19.0",
"rollup-plugin-terser": "^4.0.4",
"rollup-plugin-typescript2": "^0.19.2",
"ts-jest": "^23.10.4",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"typescript": "^3.1.6"
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.3.1"
},
"keywords": [
"mobx",
Expand Down
2 changes: 1 addition & 1 deletion src/assertEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { spy } from "mobx"
import { useState } from "react"

if (!useState) {
throw new Error("mobx-react-lite requires React with Hooks support (alpha versions)")
throw new Error("mobx-react-lite requires React with Hooks support")
}
if (!spy) {
throw new Error("mobx-react-lite requires mobx at least version 4 to be available")
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export function useUnmount(fn: () => void) {
}

export function useForceUpdate() {
const [, setTick] = useState(null)
const [, setTick] = useState(0)

const update = useCallback(() => {
setTick(null)
setTick(tick => tick + 1)
}, [])

return update
Expand Down
6 changes: 4 additions & 2 deletions test/ObserverComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mockConsole from "jest-mock-console"
import * as mobx from "mobx"
import * as React from "react"
import { cleanup, render } from "react-testing-library"
import { act, cleanup, render } from "react-testing-library"

import { Observer } from "../src"

Expand All @@ -27,7 +27,9 @@ describe("regions should rerender component", () => {

test("set the data to hello", async () => {
const { container, data } = execute()
data.set("hello")
act(() => {
data.set("hello")
})
expect(container.querySelector("span")!.innerHTML).toBe("hello")
expect(container.querySelector("li")!.innerHTML).toBe("hi")
})
Expand Down
2 changes: 1 addition & 1 deletion test/assertEnvironment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ afterEach(() => {
it("throws if react is not installed", () => {
jest.mock("react", () => ({}))
expect(() => require("../src/assertEnvironment.ts")).toThrowErrorMatchingInlineSnapshot(
`"mobx-react-lite requires React with Hooks support (alpha versions)"`
`"mobx-react-lite requires React with Hooks support"`
)
})

Expand Down
78 changes: 50 additions & 28 deletions test/observer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as mobx from "mobx"
import * as React from "react"
import { cleanup, fireEvent, render } from "react-testing-library"
import { act, cleanup, fireEvent, render } from "react-testing-library"

import { observer, useObserver, useStaticRendering } from "../src"

Expand Down Expand Up @@ -72,7 +72,9 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("inner store changed", () => {
const { store, getAllByText, renderings } = execute()
store.todos[0].title += "a"
act(() => {
store.todos[0].title += "a"
})
expect(renderings.list).toBe(1)
expect(renderings.item).toBe(2)
expect(getAllByText("1")).toHaveLength(1)
Expand All @@ -83,9 +85,11 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("rerendering with outer store added", () => {
const { store, container, getAllByText, renderings } = execute()
store.todos.push({
completed: true,
title: "b"
act(() => {
store.todos.push({
completed: true,
title: "b"
})
})
expect(container.querySelectorAll("li").length).toBe(2)
expect(getAllByText("2")).toHaveLength(1)
Expand All @@ -98,7 +102,10 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("rerendering with outer store pop", () => {
const { store, container, renderings } = execute()
const oldTodo = store.todos.pop()
let oldTodo
act(() => {
oldTodo = store.todos.pop()
})
expect(renderings.list).toBe(2)
expect(renderings.item).toBe(1)
expect(container.querySelectorAll("li").length).toBe(0)
Expand All @@ -118,7 +125,9 @@ function runTestSuite(mode: "observer" | "useObserver") {
test("does not assume React will update due to NaN prop", () => {
// @ts-ignore Not sure what this test does, the value is not used
render(<Counter value={NaN} />)
store.count++
act(() => {
store.count++
})
expect(counterRenderings).toBe(2)
})
})
Expand Down Expand Up @@ -153,7 +162,9 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("rerender should not need a recomputation of data.y", () => {
const { data, queryByText } = execute()
data.z = "hello"
act(() => {
data.z = "hello"
})
expect(data.yCalcCount).toBe(1)
expect(queryByText("hello6")).toBeTruthy()
})
Expand Down Expand Up @@ -187,7 +198,9 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("no re-rendering on static rendering", () => {
const { getRenderCount, getByText, data } = execute()
data.z = "hello"
act(() => {
data.z = "hello"
})
expect(getRenderCount()).toBe(1)
expect(getByText("hi")).toBeTruthy()
expect(getDNode(data, "z").observers.size).toBe(0)
Expand Down Expand Up @@ -243,10 +256,12 @@ function runTestSuite(mode: "observer" | "useObserver") {
test("run transaction", () => {
const data = createData()
const { container } = render(<Table data={data} />)
mobx.transaction(() => {
data.items[1].name = "boe"
data.items.splice(0, 2, { name: "soup" })
data.selected = "tea"
act(() => {
mobx.transaction(() => {
data.items[1].name = "boe"
data.items.splice(0, 2, { name: "soup" })
data.selected = "tea"
})
})
expect(container).toMatchSnapshot()
})
Expand All @@ -268,7 +283,9 @@ function runTestSuite(mode: "observer" | "useObserver") {
return <div>{data.get()}</div>
})
const { container } = render(<Comp />)
data.set(3)
act(() => {
data.set(3)
})
expect(container).toMatchSnapshot()
mobx._resetGlobalState()
})
Expand Down Expand Up @@ -391,7 +408,9 @@ function runTestSuite(mode: "observer" | "useObserver") {

test("after odata change", async () => {
const { container, renderings, odata } = execute()
odata.y++
act(() => {
odata.y++
})
expect(renderings.parent).toBe(2)
expect(renderings.child).toBe(1)
expect(container.querySelector("span")!.innerHTML).toBe("1")
Expand All @@ -402,7 +421,7 @@ function runTestSuite(mode: "observer" | "useObserver") {
runTestSuite("observer")
runTestSuite("useObserver")

test("useImperativeMethods and forwardRef should work with observer", () => {
test("useImperativeHandle and forwardRef should work with observer", () => {
interface IMethods {
focus(): void
}
Expand All @@ -414,7 +433,7 @@ test("useImperativeMethods and forwardRef should work with observer", () => {
const FancyInput = observer(
(props: IProps, ref: React.Ref<IMethods>) => {
const inputRef = React.useRef<HTMLInputElement>(null)
React.useImperativeMethods(
React.useImperativeHandle(
ref,
() => ({
focus: () => {
Expand All @@ -435,7 +454,7 @@ test("useImperativeMethods and forwardRef should work with observer", () => {
expect(typeof cr.current!.focus).toBe("function")
})

test("useImperativeMethods and forwardRef should work with useObserver", () => {
test("useImperativeHandle and forwardRef should work with useObserver", () => {
interface IMethods {
focus(): void
}
Expand All @@ -447,7 +466,7 @@ test("useImperativeMethods and forwardRef should work with useObserver", () => {
const FancyInput = React.memo(
React.forwardRef((props: IProps, ref: React.Ref<IMethods>) => {
const inputRef = React.useRef<HTMLInputElement>(null)
React.useImperativeMethods(
React.useImperativeHandle(
ref,
() => ({
focus: () => {
Expand All @@ -469,22 +488,25 @@ test("useImperativeMethods and forwardRef should work with useObserver", () => {
expect(typeof cr.current!.focus).toBe("function")
})

it('should only called new Reaction once', () => {
let renderCount = 0;
it("should only called new Reaction once", () => {
let renderCount = 0
// mock the Reaction class
const spy = jest.spyOn(mobx, 'Reaction').mockImplementation(() => (
{ track: (fn: any) => { fn() }, dispose: () => {/* nothing */ } }
))
const spy = jest.spyOn(mobx, "Reaction").mockImplementation(() => ({
track: (fn: any) => {
fn()
},
dispose: () => {
/* nothing */
}
}))
const TestComponent = observer((props: any) => {
renderCount++
return (
<div></div>
)
return <div />
})
const { rerender } = render(<TestComponent a="1" />)
rerender(<TestComponent a="2" />)
rerender(<TestComponent a="3" />)
expect(renderCount).toBe(3);
expect(renderCount).toBe(3)
expect(spy.mock.calls.length).toBe(1)
spy.mockRestore()
})
Expand Down
16 changes: 10 additions & 6 deletions test/transactions.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as mobx from "mobx"
import * as React from "react"
import { render } from "react-testing-library"
import { act, render } from "react-testing-library"

import { observer } from "../src"

Expand Down Expand Up @@ -32,7 +32,9 @@ test("mobx issue 50", done => {
render(<Test />)

setImmediate(() => {
flipStuff()
act(() => {
flipStuff()
})
expect(asText).toBe("false:true:true")
expect(document.getElementById("x")!.innerHTML).toBe("false,true,true")
expect(willReactCount).toBe(2)
Expand All @@ -55,10 +57,12 @@ it("should respect transaction", async () => {

const { container } = render(<Component />)

mobx.transaction(() => {
a.set(3)
a.set(4)
loaded.set(true)
act(() => {
mobx.transaction(() => {
a.set(3)
a.set(4)
loaded.set(true)
})
})

expect(container.textContent!.replace(/\s+/g, "")).toBe("4")
Expand Down
20 changes: 13 additions & 7 deletions test/useComputed.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { observable } from 'mobx'
import * as React from 'react'
import { cleanup, render } from 'react-testing-library'
import { observable } from "mobx"
import * as React from "react"
import { act, cleanup, render } from "react-testing-library"

import { observer, useComputed } from '../src'
import { observer, useComputed } from "../src"

afterEach(cleanup)

Expand All @@ -16,9 +16,13 @@ describe("is used to rerender based on a computed value change", () => {
const { container } = render(<TestComponent store={store} />)
const div = container.querySelector("div")!
expect(div.textContent).toBe("10")
store.y = 2
act(() => {
store.y = 2
})
expect(div.textContent).toBe("15")
store.x = 10
act(() => {
store.x = 10
})
expect(div.textContent).toBe("20")
})

Expand All @@ -33,7 +37,9 @@ describe("is used to rerender based on a computed value change", () => {
expect(div.textContent).toBe("10")
rerender(<TestComponent store={store} y={2} />)
expect(div.textContent).toBe("15")
store.x = 10
act(() => {
store.x = 10
})
expect(div.textContent).toBe("20")
})
})
Loading

0 comments on commit 384d857

Please sign in to comment.