Skip to content
This repository has been archived by the owner on Aug 1, 2018. It is now read-only.

Commit

Permalink
Support React.createContext()
Browse files Browse the repository at this point in the history
  • Loading branch information
koulmomo authored and fusion-bot[bot] committed Apr 10, 2018
1 parent 012b25f commit a2d09c0
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ const hoc = prepared(sideEffect, opts);
```

* `sideEffect: : (props: Object, context: Object) => Promise` - Required. when `prepare` is called, `sideEffect` is called (and awaited) before continuing the rendering traversal.
* `opts: {defer, boundary, componentDidMount, componentWillReceiveProps, forceUpdate, contextTypes}` - Optional
* `opts: {defer, boundary, componentDidMount, componentWillReceiveProps, componentDidUpdate, forceUpdate, contextTypes}` - Optional
* `defer: boolean` - Optional. Defaults to `true`. If the component is deferred, skip the prepare step
* `boundary: boolean` - Optional. Defaults to `false`. Stop traversing if the component is defer or boundary
* `componentDidMount: boolean` - Optional. Defaults to `true`. On the browser, `sideEffect` is called when the component is mounted.
Expand Down
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
"version": "1.2.0",
"description": "Prepare you app state for async rendering",
"repository": "fusionjs/fusion-react-async",
"files": [
"dist",
"src"
],
"files": ["dist", "src"],
"main": "./dist/index.js",
"module": "./dist/index.es.js",
"browser": {
Expand All @@ -30,7 +27,8 @@
"test": "npm run build-test && npm run just-test"
},
"dependencies": {
"prop-types": "^15.5.8"
"prop-types": "^15.5.8",
"react-is": "^16.3.1"
},
"devDependencies": {
"@babel/preset-react": "7.0.0-beta.40",
Expand All @@ -48,8 +46,8 @@
"flow-bin": "0.66.0",
"nyc": "11.4.1",
"prettier": "1.11.1",
"react": "16.2.0",
"react-dom": "16.2.0",
"react": "16.3.0",
"react-dom": "16.3.0",
"tape-cup": "4.7.1"
},
"peerDependencies": {
Expand Down
67 changes: 67 additions & 0 deletions src/__tests__/__node__/prepare-render.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,70 @@ tape('Preparing a fragment with async children', t => {
t.end();
});
});

tape('Preparing React.createContext()', t => {
const {Provider, Consumer} = React.createContext('light');

const app = (
<Provider value="light">
<span>1</span>
<Consumer>
<span>2</span>
</Consumer>
</Provider>
);
const p = prepare(app);
t.ok(p instanceof Promise, 'prepare returns a promise');
p.then(() => {
const wrapper = shallow(<div>{app}</div>);
t.equal(wrapper.find('span').length, 2, 'has two children');
t.end();
});
});

tape('Preparing React.createContext() with async children', t => {
const {Provider, Consumer} = React.createContext('light');

let numChildRenders = 0;
let numPrepares = 0;
function SimplePresentational() {
numChildRenders++;

return (
<Consumer>
{theme => {
return <div>{theme}</div>;
}}
</Consumer>
);
}
const AsyncChild = prepared(props => {
numPrepares++;
t.equal(
props.data,
'test',
'passes props through to prepared component correctly'
);
return Promise.resolve();
})(SimplePresentational);

const app = (
<Provider value="dark">
<AsyncChild data="test" />
<AsyncChild data="test" />
</Provider>
);
const p = prepare(app);
t.ok(p instanceof Promise, 'prepare returns a promise');
p.then(() => {
t.equal(numPrepares, 2, 'runs prepare function twice');
t.equal(numChildRenders, 2, 'renders SimplePresentational twice');

t.equal(
shallow(<div>{app}</div>).html(),
'<div><div>dark</div><div>dark</div></div>',
'passes values via context'
);
t.end();
});
});
8 changes: 7 additions & 1 deletion src/prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import React from 'react';
import {isFragment, isContextConsumer, isContextProvider} from 'react-is';

import isReactCompositeComponent from './utils/isReactCompositeComponent';
import {isPrepared, getPrepare} from './prepared';
Expand Down Expand Up @@ -41,7 +42,12 @@ function prepareElement(element, context) {
return Promise.resolve([null, context]);
}
const {type, props} = element;
if (typeof type === 'string' || type === React.Fragment) {
if (
typeof type === 'string' ||
isFragment(element) ||
isContextConsumer(element) ||
isContextProvider(element)
) {
return Promise.resolve([props.children, context]);
}
if (!isReactCompositeComponent(type)) {
Expand Down
16 changes: 10 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3724,15 +3724,19 @@ rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"

react-dom@16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
react-dom@16.3.0:
version "16.3.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.0.tgz#b318e52184188ecb5c3e81117420cca40618643e"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.0"

react-is@^16.3.1:
version "16.3.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.1.tgz#ee66e6d8283224a83b3030e110056798488359ba"

react-reconciler@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
Expand All @@ -3750,9 +3754,9 @@ react-test-renderer@^16.0.0-0:
object-assign "^4.1.1"
prop-types "^15.6.0"

react@16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
react@16.3.0:
version "16.3.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.3.0.tgz#fc5a01c68f91e9b38e92cf83f7b795ebdca8ddff"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.1.0"
Expand Down

0 comments on commit a2d09c0

Please sign in to comment.