Skip to content

Commit 0255718

Browse files
committed
feat(createRender): new function to pre-determine what type renderable is
which prevents these checks on every invocation
1 parent 03bba16 commit 0255718

File tree

11 files changed

+139
-59
lines changed

11 files changed

+139
-59
lines changed

.size-snapshot.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"dist/react-render-callback.cjs.js": {
3-
"bundled": 1491,
4-
"minified": 820,
5-
"gzipped": 431
3+
"bundled": 1807,
4+
"minified": 1032,
5+
"gzipped": 471
66
},
77
"dist/react-render-callback.esm.js": {
8-
"bundled": 1363,
9-
"minified": 733,
10-
"gzipped": 383,
8+
"bundled": 1651,
9+
"minified": 919,
10+
"gzipped": 422,
1111
"treeshaked": {
1212
"rollup": {
1313
"code": 78,
@@ -19,13 +19,13 @@
1919
}
2020
},
2121
"dist/react-render-callback.umd.min.js": {
22-
"bundled": 6986,
23-
"minified": 3178,
24-
"gzipped": 1118
22+
"bundled": 7332,
23+
"minified": 3333,
24+
"gzipped": 1160
2525
},
2626
"dist/react-render-callback.umd.js": {
27-
"bundled": 11501,
28-
"minified": 4775,
29-
"gzipped": 1379
27+
"bundled": 11847,
28+
"minified": 4930,
29+
"gzipped": 1417
3030
}
3131
}

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ npm install --save react-render-callback
8282

8383
### API
8484

85-
`render([ renderable [, props [, options ] ] ])`:
85+
#### `render([ renderable [, props [, options ] ] ])`
86+
87+
> renders the given `renderable` with `props`
8688
8789
- `renderable` (optional): anything that can be rendered like a function, a component, or elements
8890
- invokes stateless function components (SFC) respecting their
@@ -119,6 +121,24 @@ npm install --save react-render-callback
119121
- `null` for `false`, `null`, `undefined`, `NaN` and an empty string
120122
- the value as is for all other values
121123

124+
#### `createRender([ renderable [, options ] ])`
125+
126+
> Returns a function (`(props) => ...`) to render `renderable` with `props`.
127+
128+
Accepts the same arguments (except `props`) as `render()`. It exists mainly
129+
to pre-determine (read cache) what type `renderable` is, to prevent these
130+
checks on every invocation.
131+
132+
This function is available via
133+
134+
```js
135+
import {createRender} from 'react-render-callback'
136+
```
137+
138+
```js
139+
const {createRender} = require('react-render-callback')
140+
```
141+
122142
### Example
123143

124144
```js

other/misc-tests/__tests__/build.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
* This file is unable to validate the global export.
1111
*/
1212

13-
/* eslint-disable import/extensions, import/no-unresolved */
13+
/* eslint-disable import/extensions, import/no-unresolved */
1414

15-
import esImport from '../../../dist/react-render-callback.esm'
15+
import * as esImport from '../../../dist/react-render-callback.esm'
1616

17-
import cjsImport from '../../../' // picks up the main from package.json
17+
import * as cjsImport from '../../../' // picks up the main from package.json
1818

19-
import umdImport from '../../../dist/react-render-callback.umd'
19+
import * as umdImport from '../../../dist/react-render-callback.umd'
2020

2121
// intentionally left out because you shouldn't ever
2222
// try to require the ES file in CommonJS
@@ -25,21 +25,42 @@ const cjsRequire = require('../../../') // picks up the main from package.json
2525
const umdRequire = require('../../../dist/react-render-callback.umd')
2626

2727
test(`import render from 'react-render-callback/dist/react-render-callback.esm'`, () => {
28-
expect(esImport).toBeInstanceOf(Function)
28+
expect(esImport.default).toBeInstanceOf(Function)
29+
})
30+
test(`import {render} from 'react-render-callback/dist/react-render-callback.esm'`, () => {
31+
expect(esImport.render).toBeInstanceOf(Function)
32+
})
33+
test(`import {createRender} from 'react-render-callback/dist/react-render-callback.esm'`, () => {
34+
expect(esImport.createRender).toBeInstanceOf(Function)
2935
})
3036

3137
test(`import render from 'react-render-callback'`, () => {
32-
expect(cjsImport).toBeInstanceOf(Function)
38+
expect(cjsImport.default).toBeInstanceOf(Function)
39+
expect(cjsImport.render).toBeInstanceOf(Function)
40+
expect(cjsImport.createRender).toBeInstanceOf(Function)
41+
})
42+
43+
test(`import {render} from 'react-render-callback'`, () => {
44+
expect(cjsImport.render).toBeInstanceOf(Function)
45+
})
46+
test(`import {createRender} from 'react-render-callback'`, () => {
47+
expect(cjsImport.createRender).toBeInstanceOf(Function)
3348
})
3449

3550
test(`import render from 'react-render-callback/dist/react-render-callback.umd'`, () => {
36-
expect(umdImport).toBeInstanceOf(Function)
51+
expect(umdImport.default).toBeInstanceOf(Function)
52+
expect(umdImport.render).toBeInstanceOf(Function)
53+
expect(umdImport.createRender).toBeInstanceOf(Function)
3754
})
3855

3956
test(`const render = require('react-render-callback')`, () => {
4057
expect(cjsRequire).toBeInstanceOf(Function)
58+
expect(cjsRequire.render).toBeInstanceOf(Function)
59+
expect(cjsRequire.createRender).toBeInstanceOf(Function)
4160
})
4261

4362
test(`const render = require('react-render-callback/dist/react-render-callback.umd')`, () => {
4463
expect(umdRequire).toBeInstanceOf(Function)
64+
expect(umdRequire.render).toBeInstanceOf(Function)
65+
expect(umdRequire.createRender).toBeInstanceOf(Function)
4566
})

src/createRender.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {isValidElement, createElement, cloneElement} from 'react'
2+
3+
import isReactComponent from './internal/isReactComponent'
4+
import maybeFalsy from './internal/maybeFalsy'
5+
6+
export default (renderable, options) => {
7+
if (isReactComponent(renderable)) {
8+
return props => createElement(renderable, props)
9+
}
10+
11+
if (typeof renderable === 'function') {
12+
return maybeFalsy(props =>
13+
renderable({...renderable.defaultProps, ...props}),
14+
)
15+
}
16+
17+
if (options && options.cloneElement && isValidElement(renderable)) {
18+
return props => cloneElement(renderable, props)
19+
}
20+
21+
// must be something else
22+
return maybeFalsy(() => renderable)
23+
}

src/esm-entry.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export {default} from './render'
2+
3+
export {default as render} from './render'
4+
export {default as createRender} from './createRender'

src/esm-entry.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import render from './render'
2+
import createRender from './createRender'
3+
4+
import * as Export from './esm-entry'
5+
6+
test('the default export is render', () => {
7+
expect(Export.default).toBe(render)
8+
})
9+
10+
test('named export render', () => {
11+
expect(Export.render).toBe(render)
12+
})
13+
14+
test('named export createRender', () => {
15+
expect(Export.createRender).toBe(createRender)
16+
})

src/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
export {default} from './render'
1+
import render from './render'
2+
3+
import createRender from './createRender'
4+
5+
render.render = render
6+
render.createRender = createRender
7+
8+
export default render

src/index.test.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import render from './render'
2+
import createRender from './createRender'
23

3-
import defaultExport from '.'
4+
import Export from '.'
45

56
test('the default export is render', () => {
6-
expect(defaultExport).toBe(render)
7-
})
7+
expect(Export).toBe(render)
8+
})
9+
10+
test('named export render', () => {
11+
expect(Export.render).toBe(render)
12+
})
13+
14+
test('named export createRender', () => {
15+
expect(Export.createRender).toBe(createRender)
16+
})

src/internal/isFalsy.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default value =>
2+
value == null ||
3+
value === false ||
4+
value === '' ||
5+
(typeof value === 'number' && isNaN(value))

src/internal/maybeFalsy.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import isFalsy from './isFalsy'
2+
3+
export default render => props => {
4+
const element = render(props)
5+
6+
return isFalsy(element) ? null : element
7+
}

0 commit comments

Comments
 (0)