Skip to content

Commit

Permalink
fix(store): throw error when hooks used below react 16.8
Browse files Browse the repository at this point in the history
  • Loading branch information
rolandszoke authored and solkimicreb committed Mar 2, 2020
1 parent e2b1034 commit 152ec88
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 49 deletions.
3 changes: 3 additions & 0 deletions __mocks__/@testing-library/react/pure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = process.env.NOHOOK
? require('no-hook-react-testing-library')
: require('@testing-library/react/pure');
3 changes: 3 additions & 0 deletions __mocks__/react-dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = process.env.NOHOOK
? require('no-hook-react-dom')
: require('react-dom');
5 changes: 4 additions & 1 deletion __mocks__/react.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// this is here to avoid duplicate react entries in the examples
// (one from the example's node_modules and one from the root's node_modules)
module.exports = require('react');

module.exports = process.env.NOHOOK
? require('no-hook-react')
: require('react');
17 changes: 17 additions & 0 deletions __tests__/functionComponent.test.no-hook.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { render } from '@testing-library/react/pure';
// eslint-disable-next-line import/no-unresolved
import { view, store } from 'react-easy-state';

describe('Using an old react version', () => {
test('Using local state in a function component with a version of react that has no hooks should throw an error', () => {
const MyComp = view(() => {
const person = store({ name: 'Bob' });
return <div>{person.name}</div>;
});

expect(() => render(<MyComp />)).toThrow(
'You cannot use state inside a function component with a pre-hooks version of React. Please update your React version to at least v16.8.0 to use this feature.',
);
});
});
14 changes: 0 additions & 14 deletions __tests__/functionComponentNoHooks.test.js

This file was deleted.

8 changes: 8 additions & 0 deletions jest.no-hook.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"setupFilesAfterEnv": ["./scripts/testSetup.js"],
"testRegex": "\\.test\\.no-hook\\.jsx?$",
"collectCoverage": true,
"coverageReporters": ["lcovonly", "text"],
"collectCoverageFrom": ["src/**/*.{js,jsx}"],
"coverageDirectory": "coverage"
}
108 changes: 83 additions & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"scripts": {
"test-native": "NATIVE=true jest --config ./jest.native.json",
"test-web": "jest --config ./jest.web.json",
"test": "npm run test-web && npm run test-native",
"old-test": "npm run test-web && npm run test-native",
"test-web-no-hook": "NOHOOK=true jest --config ./jest.no-hook.json",
"test": "npm run test-web && npm run test-web-no-hook && npm run test-native",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"test-builds": "node ./scripts/testBuilds.js",
"lint": "eslint --max-warnings 0 --ext js,jsx src scripts",
Expand Down Expand Up @@ -60,8 +60,7 @@
"es6 proxy"
],
"dependencies": {
"@nx-js/observer-util": "^4.2.2",
"old-react-dom": "npm:react-dom@^16.7.0"
"@nx-js/observer-util": "^4.2.2"
},
"peerDependencies": {
"react": "*"
Expand Down Expand Up @@ -96,8 +95,9 @@
"markdown-toc": "^1.2.0",
"moment": "^2.24.0",
"nyc": "^15.0.0",
"old-react": "npm:react@16.7.0",
"old-react-dom": "npm:react-dom@16.7.0",
"no-hook-react": "npm:react@16.7.0",
"no-hook-react-dom": "npm:react-dom@16.7.0",
"no-hook-react-testing-library": "npm:react-testing-library@5.4.4",
"prettier": "^1.19.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
Expand Down
9 changes: 6 additions & 3 deletions src/store.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { useMemo } from 'react';
import { observable } from '@nx-js/observer-util';

import { isInsideFunctionComponent } from './view';
import {
isInsideFunctionComponent,
isInsideStatelessComp,
} from './view';
import { hasHooks } from './utils';

export function store(obj) {
// do not create new versions of the store on every render
// if it is a local store in a function component
// create a memoized store at the first call instead
if (hasHooks && isInsideFunctionComponent) {
if (isInsideFunctionComponent) {
return useMemo(() => observable(obj), []);
}
if (!hasHooks && isInsideFunctionComponent) {
if (!hasHooks && isInsideStatelessComp) {
throw new Error(
'You cannot use state inside a function component with a pre-hooks version of React. Please update your React version to at least v16.8.0 to use this feature.',
);
Expand Down
2 changes: 2 additions & 0 deletions src/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { hasHooks } from './utils';
import { queue } from './queue';

export let isInsideFunctionComponent = false;
export let isInsideStatelessComp = false;
const COMPONENT = Symbol('owner component');
const TRIGGERRENDER = Symbol('trigger render');

Expand All @@ -35,6 +36,7 @@ export function view(Comp) {
const isStatelessComp = !(
Comp.prototype && Comp.prototype.isReactComponent
);
isInsideStatelessComp = isStatelessComp;

let ReactiveComp;

Expand Down

0 comments on commit 152ec88

Please sign in to comment.