Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jamesplease/react-composer
Compose render prop components
https://github.com/jamesplease/react-composer
props react render
Last synced: 7 days ago
JSON representation
Compose render prop components
- Host: GitHub
- URL: https://github.com/jamesplease/react-composer
- Owner: jamesplease
- License: mit
- Created: 2018-01-20T23:57:29.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-04-28T19:21:52.000Z (over 2 years ago)
- Last Synced: 2024-05-23T01:41:30.683Z (8 months ago)
- Topics: props, react, render
- Language: JavaScript
- Size: 77.1 KB
- Stars: 612
- Watchers: 2
- Forks: 17
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- awesome-react-render-props - react-composer
- awesome-github-repos - jamesplease/react-composer - Compose render prop components (JavaScript)
- awesome-react-state-management - react-composer - Prevents deeply nested code when consuming multiple contexts at the same time. (List)
- awesome-react-context - **react-composer** - Prevents deeply nested code when consuming multiple contexts at the same time. (Libraries)
README
# React Composer
[![Travis build status](http://img.shields.io/travis/jamesplease/react-composer.svg?style=flat)](https://travis-ci.org/jamesplease/react-composer)
[![npm version](https://img.shields.io/npm/v/react-composer.svg)](https://www.npmjs.com/package/react-composer)
[![npm downloads](https://img.shields.io/npm/dm/react-composer.svg)](https://www.npmjs.com/package/react-composer)
[![Test Coverage](https://coveralls.io/repos/github/jamesplease/react-composer/badge.svg?branch=master)](https://coveralls.io/github/jamesplease/react-composer?branch=master)
[![gzip size](http://img.badgesize.io/https://unpkg.com/react-composer/dist/react-composer.min.js?compression=gzip)](https://unpkg.com/react-composer/dist/react-composer.min.js)Compose [render prop](https://reactjs.org/docs/render-props.html) components.
## Motivation
Render props are great. Using a component with a render prop looks like the following:
```jsx
{result => }
```
Sometimes you need the result of multiple render prop components inside of `MyComponent`. This
can get messy.```jsx
{resultOne => (
{resultTwo => (
{resultThree => (
)}
)}
)}```
Nesting render prop components leads to rightward drift of your code. Use React Composer to
prevent that drift.```jsx
import Composer from 'react-composer';,
,
]}>
{([resultOne, resultTwo, resultThree]) => (
)}
;
```## Installation
Install using [npm](https://www.npmjs.com):
```
npm install react-composer
```or [yarn](https://yarnpkg.com/):
```
yarn add react-composer
```## API
This library has one, default export: `Composer`.
### ``
Compose multiple render prop components together. The props are as
follows:### `props.children`
A render function that is called with an array of results accumulated from the render prop components.
```jsx
{results => {
/* Do something with results... Return a valid React element. */
}}```
### `props.components`
The render prop components to compose. This is an array of [React elements](https://reactjs.org/docs/glossary.html#elements) and/or render functions that are invoked with a render function and the currently accumulated results.
```jsx
,// Render functions may be passed for added flexibility and control
({ results, render }) => (
)
]}>
{([outerResult, middleResult]) => {
/* Do something with results... Return a valid React element. */
}}```
> **Note:** You do not need to provide `props.children` to the React element entries in `props.components`. If you do provide `props.children` to these elements, it will be ignored and overwritten.
#### `props.components` as render functions
A render function may be passed instead of a React element for added flexibility.
Render functions provided must return a valid React element. Render functions will be invoked with an object containing 2 properties:
1. `results`: The currently accumulated results. You can use this for render prop components which depend on the results of other render prop components.
2. `render`: The render function for the component to invoke with the value produced. Plug this into your render prop component. This will typically be plugged in as `props.children` or `props.render`.```jsx
,
({ /* results, */ render }) =>
]}>
{results => {
/* Do something with results... */
}}```
## Examples and Guides
### Example: Render prop component(s) depending on the result of other render prop component(s)
```jsx
,
({ results: [outerResult], render }) => (
),
({ results, render }) => (
)
// ...
]}>
{([outerResult, middleResult, innerResult]) => {
/* Do something with results... */
}}```
### Example: Render props named other than `props.children`.
By default, `` will enhance your React elements with `props.children`.
Render prop components typically use `props.children` or `props.render` as their render prop. Some even accept both. For cases when your render prop component's render prop is not `props.children` you can plug `render` in directly yourself. Example:
```jsx
,
({ render }) => ,
({ render }) => ,
({ render }) =>
// ...
]}>
{results => {
/* Do something with results... */
}}```
### Example: Render prop component(s) that produce multiple arguments
Example of how to handle cases when a component passes multiple arguments to its render prop rather than a single argument.
```jsx
,
// Differing render prop signature (multi-arg producers)
({ render }) => (
{(one, two) => render([one, two])}
),
]}>
{([outerResult, [one, two], innerResult]) => {
/* Do something with results... */
}}```
### Limitations
This library only works for render prop components that have a single render
prop. So, for instance, this library will not work if your component has an API like the following:```jsx
```
### Render Order
The first item in the `components` array will be the outermost component that is rendered. So, for instance,
if you pass```jsx
, , ]}>
```then your tree will render like so:
```
- A
- B
- C
```### Console Warnings
Render prop components often specify with [PropTypes](https://reactjs.org/docs/typechecking-with-proptypes.html)
that the render prop is required. When using these components with React Composer, you may get a warning in the
console.One way to eliminate the warnings is to define the render prop as an empty function knowning that `Composer` will
overwrite it with the real render function.```jsx
null} />
]}
// ...
>
```Alternatively, you can leverage the flexibility of the `props.components` as functions API and plug the render function in directly yourself.
```jsx
]}
// ...
>
```### Example Usage
Here are some examples of render prop components that benefit from React Composer:
* React's [Context API](https://reactjs.org/docs/context.html). See [this example](https://codesandbox.io/s/92pj14134y) by [Kent Dodds](https://twitter.com/kentcdodds).
* [React Request](https://github.com/jamesplease/react-request)
* Apollo's [Query component](https://www.apollographql.com/docs/react/essentials/queries.html#basic)Do you know of a component that you think benefits from React Composer? Open a Pull Request and add it to the list!
## Contributing
Are you interested in helping out with this project? That's awesome – thank you! Head on over to
[the contributing guide](./CONTRIBUTING.md) to get started.