From d9e721122e13cd690cac7e46c1fbe9835b2b2006 Mon Sep 17 00:00:00 2001 From: David Gilbertson Date: Wed, 15 Apr 2020 10:03:38 +1000 Subject: [PATCH] Update demo site --- demo/README.md | 10 ++++ demo/src/App.js | 5 +- demo/src/index.js | 5 +- .../pages/batchedUpdates/BatchedUpdates.js | 58 +++++++++++++++++++ demo/src/pages/batchedUpdates/Child.js | 26 +++++++++ demo/src/pages/batchedUpdates/Parent.js | 26 +++++++++ demo/src/pages/bigTree/Item.js | 2 +- demo/src/pages/bigTree/selectors.js | 2 +- demo/src/pages/bigTree/updaters.js | 2 +- demo/src/pages/bigTree/utils.js | 2 +- demo/src/pages/products/Products.js | 2 +- .../products/propTypes/ProductPagePropType.js | 2 +- demo/src/pages/todomvc/components/Footer.js | 2 +- demo/src/pages/todomvc/components/Link.js | 2 +- .../pages/todomvc/components/TodoMvcPage.js | 2 +- .../todomvc/propTypes/TodoMvcPropType.js | 2 +- .../todomvc/selectors/getVisibleTodos.js | 2 +- .../pages/todomvc/selectors/loadTodoData.js | 2 +- demo/src/propTypes/StorePropType.js | 2 +- .../{pages/todomvc => shared}/constants.js | 1 + 20 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 demo/src/pages/batchedUpdates/BatchedUpdates.js create mode 100644 demo/src/pages/batchedUpdates/Child.js create mode 100644 demo/src/pages/batchedUpdates/Parent.js rename demo/src/{pages/todomvc => shared}/constants.js (92%) diff --git a/demo/README.md b/demo/README.md index 4401561..d1cefba 100644 --- a/demo/README.md +++ b/demo/README.md @@ -28,6 +28,16 @@ npm link ../ Now imports of `'react-recollect'` in the demo site will load from `react-recollect/dist`. +Running `npm i` will undo this link, in which case you'll need to do it again to +relink. + +Beware! Since this directory will have a `node_modules` directory, `react-dom` +may be loaded from there, rather than the `demo/node_modules` directory. To be +100% certain you're replicating what users get, you'll want to release as a +prerelease and install it from npm. This is also required to test that when the +package is installed, it doesn't install any `node_modules` when it shouldn't +(e.g. it should share hoistNonReactStatics with material-ui). + Unlink with `npm i react-recollect`. Start the demo site: diff --git a/demo/src/App.js b/demo/src/App.js index a7c0c25..6ff59b5 100644 --- a/demo/src/App.js +++ b/demo/src/App.js @@ -8,10 +8,11 @@ import Typography from '@material-ui/core/Typography'; import React from 'react'; import { collect } from 'react-recollect'; import './App.css'; +import BatchedUpdates from './pages/batchedUpdates/BatchedUpdates'; import BigTree from './pages/bigTree/BigTree'; import Products from './pages/products/Products'; import TodoMvcPage from './pages/todomvc/components/TodoMvcPage'; -import { PAGES } from './pages/todomvc/constants'; +import { PAGES } from './shared/constants'; import StorePropType from './propTypes/StorePropType'; const App = ({ store }) => ( @@ -39,6 +40,8 @@ const App = ({ store }) => ( {store.currentPage === PAGES.PRODUCTS && } + {store.currentPage === PAGES.BATCHED_UPDATES && } + {store.currentPage === PAGES.BIG_TREE && ( diff --git a/demo/src/index.js b/demo/src/index.js index d4be568..58e98c8 100644 --- a/demo/src/index.js +++ b/demo/src/index.js @@ -11,12 +11,15 @@ import { PRODUCT_FILTER, TYPES, VISIBILITY_FILTERS, -} from './pages/todomvc/constants'; +} from './shared/constants'; import Theme from './shared/Theme'; initStore({ currentPage: localStorage.currentPage || PAGES.PRODUCTS, loading: false, + batchUpdatePage: { + text: '×', + }, productPage: { filter: PRODUCT_FILTER.ALL, products: [], diff --git a/demo/src/pages/batchedUpdates/BatchedUpdates.js b/demo/src/pages/batchedUpdates/BatchedUpdates.js new file mode 100644 index 0000000..ac43d78 --- /dev/null +++ b/demo/src/pages/batchedUpdates/BatchedUpdates.js @@ -0,0 +1,58 @@ +import Container from '@material-ui/core/Container'; +import React from 'react'; +import { collect } from 'react-recollect'; +import StorePropType from '../../propTypes/StorePropType'; +import Parent from './Parent'; + +class BatchedUpdates extends React.Component { + renderCount = 1; + + update = () => { + this.props.store.batchUpdatePage.text += '×'; + }; + + render() { + return ( + +

Render count: {this.renderCount++}

+ +

+ When functioning correctly, clicking either button below triggers only + a single render for each component +

+ +
+

+ This changes the store within an onClick handler. In this case, React + will batch updates and trigger a single render by default +

+ + +
+ +

+ This changes the store outside of a onClick handler (in a setTimeout + callback). In this case, React can’t batch updates, but the batching + is handled internally by Recollect. +

+ + +
+ + +
+ ); + } +} + +BatchedUpdates.propTypes = { + store: StorePropType.isRequired, +}; + +export default collect(BatchedUpdates); diff --git a/demo/src/pages/batchedUpdates/Child.js b/demo/src/pages/batchedUpdates/Child.js new file mode 100644 index 0000000..1c7ed6e --- /dev/null +++ b/demo/src/pages/batchedUpdates/Child.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { collect, PropTypes } from 'react-recollect'; +import StorePropType from '../../propTypes/StorePropType'; + +class Child extends React.Component { + renderCount = 1; + + render() { + const { text } = this.props.store.batchUpdatePage; + + return ( +
+

{`Child renders: ${this.renderCount++}`}

+

{`Child value: ${text}`}

+

{`Child value fromParent: ${this.props.fromParent}`}

+
+ ); + } +} + +Child.propTypes = { + fromParent: PropTypes.string.isRequired, + store: StorePropType.isRequired, +}; + +export default collect(Child); diff --git a/demo/src/pages/batchedUpdates/Parent.js b/demo/src/pages/batchedUpdates/Parent.js new file mode 100644 index 0000000..c82dcf0 --- /dev/null +++ b/demo/src/pages/batchedUpdates/Parent.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { collect } from 'react-recollect'; +import StorePropType from '../../propTypes/StorePropType'; +import Child from './Child'; + +class Parent extends React.Component { + renderCount = 1; + + render() { + const { text } = this.props.store.batchUpdatePage; + + return ( +
+

{`Parent renders: ${this.renderCount++}`}

+

{`Parent value: ${text}`}

+ +
+ ); + } +} + +Parent.propTypes = { + store: StorePropType.isRequired, +}; + +export default collect(Parent); diff --git a/demo/src/pages/bigTree/Item.js b/demo/src/pages/bigTree/Item.js index 5abedb3..7741c91 100644 --- a/demo/src/pages/bigTree/Item.js +++ b/demo/src/pages/bigTree/Item.js @@ -7,7 +7,7 @@ import { Delete } from '@material-ui/icons'; import TreeItem from '@material-ui/lab/TreeItem'; import React, { useRef } from 'react'; import { PropTypes } from 'react-recollect'; -import { TYPES } from '../todomvc/constants'; +import { TYPES } from '../../shared/constants'; import { getChildrenAsArray } from './selectors'; import { deleteChild } from './updaters'; import { makeItem } from './utils'; diff --git a/demo/src/pages/bigTree/selectors.js b/demo/src/pages/bigTree/selectors.js index 8d7e25e..38b523b 100644 --- a/demo/src/pages/bigTree/selectors.js +++ b/demo/src/pages/bigTree/selectors.js @@ -1,4 +1,4 @@ -import { TYPES } from '../todomvc/constants'; +import { TYPES } from '../../shared/constants'; export const getChildrenAsArray = (item) => { if (item.childrenType === TYPES.OBJ) { diff --git a/demo/src/pages/bigTree/updaters.js b/demo/src/pages/bigTree/updaters.js index 5d30ea1..311d974 100644 --- a/demo/src/pages/bigTree/updaters.js +++ b/demo/src/pages/bigTree/updaters.js @@ -1,4 +1,4 @@ -import { TYPES } from '../todomvc/constants'; +import { TYPES } from '../../shared/constants'; export const deleteChild = (parent, child) => { if (parent.childrenType === TYPES.OBJ) { diff --git a/demo/src/pages/bigTree/utils.js b/demo/src/pages/bigTree/utils.js index a219483..cd913f4 100644 --- a/demo/src/pages/bigTree/utils.js +++ b/demo/src/pages/bigTree/utils.js @@ -1,4 +1,4 @@ -import { TYPES } from '../todomvc/constants'; +import { TYPES } from '../../shared/constants'; let id = 99; diff --git a/demo/src/pages/products/Products.js b/demo/src/pages/products/Products.js index 6ef3eb4..21fdf90 100644 --- a/demo/src/pages/products/Products.js +++ b/demo/src/pages/products/Products.js @@ -9,7 +9,7 @@ import Typography from '@material-ui/core/Typography'; import React from 'react'; import { collect } from 'react-recollect'; import StorePropType from '../../propTypes/StorePropType'; -import { PRODUCT_FILTER } from '../todomvc/constants'; +import { PRODUCT_FILTER } from '../../shared/constants'; import Product from './Product'; import styles from './Products.module.css'; diff --git a/demo/src/pages/products/propTypes/ProductPagePropType.js b/demo/src/pages/products/propTypes/ProductPagePropType.js index 5e39fe5..12201a1 100644 --- a/demo/src/pages/products/propTypes/ProductPagePropType.js +++ b/demo/src/pages/products/propTypes/ProductPagePropType.js @@ -1,5 +1,5 @@ import { PropTypes } from 'react-recollect'; -import { PRODUCT_FILTER } from '../../todomvc/constants'; +import { PRODUCT_FILTER } from '../../../shared/constants'; import ProductPropType from './ProductPropType'; const ProductPagePropType = PropTypes.shape({ diff --git a/demo/src/pages/todomvc/components/Footer.js b/demo/src/pages/todomvc/components/Footer.js index bb5580c..363ed0c 100644 --- a/demo/src/pages/todomvc/components/Footer.js +++ b/demo/src/pages/todomvc/components/Footer.js @@ -1,7 +1,7 @@ import React from 'react'; import { collect, PropTypes } from 'react-recollect'; import StorePropType from '../../../propTypes/StorePropType'; -import { VISIBILITY_FILTERS } from '../constants'; +import { VISIBILITY_FILTERS } from '../../../shared/constants'; import Link from './Link'; const Footer = (props) => { diff --git a/demo/src/pages/todomvc/components/Link.js b/demo/src/pages/todomvc/components/Link.js index b7abd85..9d3294d 100644 --- a/demo/src/pages/todomvc/components/Link.js +++ b/demo/src/pages/todomvc/components/Link.js @@ -2,7 +2,7 @@ import classnames from 'classnames'; import React from 'react'; import { collect, PropTypes } from 'react-recollect'; import StorePropType from '../../../propTypes/StorePropType'; -import { VISIBILITY_FILTERS } from '../constants'; +import { VISIBILITY_FILTERS } from '../../../shared/constants'; const Link = ({ filter, children, store }) => (