├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── modules
├── .babelrc
├── .eslintrc
├── Broadcast.js
├── Subscriber.js
├── __tests__
│ ├── .eslintrc
│ ├── Subscriber-test.js
│ ├── createContext-test.js
│ └── integration-test.js
├── createContext.js
├── createDeprecationWarning.js
└── index.js
├── package.json
├── scripts
├── build.js
└── config.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
3 | cjs
4 | esm
5 | umd
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: node
3 | cache:
4 | directories:
5 | - "$HOME/.cache/yarn"
6 | - node_modules
7 | env:
8 | global:
9 | - secure: pN5iwVeB1hwx0OxzqZ13DzveMkaDmJnw4jPqIYMnnp3G281tAH77SpTqrh7Jg/lrDAyZKNNlvOa6kEK5Ue7Jd5XMCmYvkaAS3gm+uiQV8GNyhD1sfANuzgKAKjB+RGIcWNGe26dRSlKqdbY4gJcqgqqNS2t28kZw9x8P+ExfrfZZTZI4ChCJMJnOA/Nzron+RpJEUCM3nGE0Nzpdrri1E+n4K3WUEM7YGm8qy+O5rxqGwgKYm8frBfE/Rm8Sz+Y4Z0gWdHc92M7lL7JBHHJoDBoGPdyB8I2Cj2Gvzh4qebfJrv+7ar+9nda9VTA9tSaoHn69Mma4rqGQhkD7R3RHDL9ZKy7KuMsDLoIMRCwqKamyzzKhAQjyeZU+CLvE3PoQanIA4oTCjupTWTtfw8f2XCTd8zg8qIzewAg7/qqgUKx2HYyNMsP0xqeYTTVMWChAZ2NhPtDNY8ktt0jjGlL5sltsWzSl2CIx7zFV1W9kkLjdxZublaASA4ouNG4rXSN+eQeHDb/E5WVxNcz9NIDfgGfiGbxb7e+Boz5Cbm+Yz/VZAS35TuU1Q46HiBi2IPjqtbgAG+zq+l01jgDBtF3vnu5iYK88Wyd5Oz+q+LFxpiAxTMhJb3dr65ezG8s/nFNZrJWBRIa78jKTkJSEx8WeBwhAuL1TKi/ROn+famgMhHw=
10 | - NPM_TAG=$([[ "$TRAVIS_TAG" == *-* ]] && echo "next" || echo "latest")
11 | deploy:
12 | provider: npm
13 | email: npm@mjackson.me
14 | api_key: "$NPM_TOKEN"
15 | tag: "$NPM_TAG"
16 | skip_cleanup: true
17 | on:
18 | all_branches: true
19 | condition: '"$TRAVIS_TAG" =~ ^v[0-9]'
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) React Training 2016-2018
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-broadcast [![Travis][build-badge]][build] [![npm package][npm-badge]][npm]
2 |
3 | [build-badge]: https://img.shields.io/travis/ReactTraining/react-broadcast/master.svg?style=flat-square
4 | [build]: https://travis-ci.org/ReactTraining/react-broadcast
5 | [npm-badge]: https://img.shields.io/npm/v/react-broadcast.svg?style=flat-square
6 | [npm]: https://www.npmjs.com/package/react-broadcast
7 |
8 | [`react-broadcast`](https://www.npmjs.com/package/react-broadcast) provides a reliable way for React components to propagate state changes to their descendants deep in the component hierarchy, bypassing intermediaries who `return false` from [`shouldComponentUpdate`](https://reactjs.org/docs/react-component.html#shouldcomponentupdate).
9 |
10 | It was originally built to solve issues that arose from using [`react-router`](https://www.npmjs.com/package/react-router) together with [`react-redux`](https://www.npmjs.com/package/react-redux). The router needed a safe way to communicate state changes to ``s deep in the component hierarchy, but `react-redux` relies on `shouldComponentUpdate` for performance. `react-broadcast` allows the router to work seamlessly with Redux and any other component that uses `shouldComponentUpdate`.
11 |
12 | **Please note:** As with anything that uses [context](https://reactjs.org/docs/context.html), this library is experimental. It may cease working in some future version of React. For now, it's a practical workaround for the router. If we discover some better way to do things in the future, rest assured we'll do our best to share what we learn.
13 |
14 | ## Installation
15 |
16 | $ npm install --save react-broadcast
17 |
18 | Then, use as you would anything else:
19 |
20 | ```js
21 | // using ES6 modules
22 | import { createContext } from "react-broadcast";
23 |
24 | // using CommonJS modules
25 | var createContext = require("react-broadcast").createContext;
26 | ```
27 |
28 | The UMD build is also available on [unpkg](https://unpkg.com):
29 |
30 | ```html
31 |
32 | ```
33 |
34 | You can find the library on `window.ReactBroadcast`.
35 |
36 | ## Usage
37 |
38 | The following is a contrived example, but illustrates the basic functionality we're after:
39 |
40 | ```js
41 | import React from "react";
42 | import { createContext } from "react-broadcast";
43 |
44 | const users = [{ name: "Michael Jackson" }, { name: "Ryan Florence" }];
45 |
46 | const { Provider, Consumer } = createContext(users[0]);
47 |
48 | class UpdateBlocker extends React.Component {
49 | shouldComponentUpdate() {
50 | // This is how you indicate to React's reconciler that you don't
51 | // need to be updated. It's a great way to boost performance when
52 | // you're sure (based on your props and state) that your render
53 | // output will not change, but it makes it difficult for libraries
54 | // to communicate changes down the hierarchy that you don't really
55 | // know anything about.
56 | return false;
57 | }
58 |
59 | render() {
60 | return this.props.children;
61 | }
62 | }
63 |
64 | class App extends React.Component {
65 | state = {
66 | currentUser: Provider.defaultValue
67 | };
68 |
69 | componentDidMount() {
70 | // Randomly change the current user every 2 seconds.
71 | setInterval(() => {
72 | const index = Math.floor(Math.random() * users.length);
73 | this.setState({ currentUser: users[index] });
74 | }, 2000);
75 | }
76 |
77 | render() {
78 | return (
79 |
80 |
81 |
82 | {currentUser =>