UNPKG

4.94 kBMarkdownView Raw
1# React Gateway
2
3> Render React DOM into a new context (aka "Portal")
4
5This can be used to implement various UI components such as modals.
6See [`react-modal2`](https://github.com/cloudflare/react-modal2).
7
8It also works in universal (isomorphic) React applications without any
9additional setup and in React Native applications
10[when used correctly](#react-native-example).
11
12## Installation
13
14```sh
15$ npm install --save react-gateway
16```
17
18## Example
19
20```js
21import React from 'react';
22import {
23 Gateway,
24 GatewayDest,
25 GatewayProvider
26} from 'react-gateway';
27
28export default class Application extends React.Component {
29 render() {
30 return (
31 <GatewayProvider>
32 <div>
33 <h1>React Gateway Universal Example</h1>
34 <div className="container">
35 <Gateway into="one">
36 <div className="item">Item 1</div>
37 </Gateway>
38 <Gateway into="two">
39 <div className="item">Item 2</div>
40 </Gateway>
41 <div className="item">Item 3</div>
42 </div>
43 <GatewayDest name="one" component="section" className="hello"/>
44 <GatewayDest name="two"/>
45 </div>
46 </GatewayProvider>
47 );
48 }
49}
50```
51
52Will render as:
53
54```js
55<div>
56 <h1>React Gateway Universal Example</h1>
57 <div className="container">
58 <noscript></noscript>
59 <noscript></noscript>
60 <div className="item">Item 3</div>
61 </div>
62 <section className="hello">
63 <div className="item">Item 1</div>
64 </section>
65 <div>
66 <div className="item">Item 2</div>
67 </div>
68</div>
69```
70
71## Usage
72
73To get started with React Gateway, first wrap your application in the
74`<GatewayProvider>`.
75
76```diff
77 import React from 'react';
78+ import {
79+ GatewayProvider
80+ } from 'react-gateway';
81
82 export default class Application extends React.Component {
83 render() {
84 return (
85+ <GatewayProvider>
86 <div>
87 {this.props.children}
88 </div>
89+ </GatewayProvider>
90 );
91 }
92 }
93```
94
95Then insert a `<GatewayDest>` whereever you want it to render and give it a
96name.
97
98```diff
99 import React from 'react';
100 import {
101 GatewayProvider,
102+ GatewayDest
103 } from 'react-gateway';
104
105 export default class Application extends React.Component {
106 render() {
107 return (
108 <GatewayProvider>
109 <div>
110 {this.props.children}
111+ <GatewayDest name="global"/>
112 </div>
113 </GatewayProvider>
114 );
115 }
116 }
117```
118
119Then in any of your components (that get rendered inside of the
120`<GatewayProvider>`) add a `<Gateway>`.
121
122```diff
123 import React from 'react';
124+ import {Gateway} from 'react-gateway';
125
126 export default class MyComponent extends React.Component {
127 render() {
128 return (
129 <div>
130+ <Gateway into="global">
131+ Will render into the "global" gateway.
132+ </Gateway>
133 </div>
134 );
135 }
136 }
137```
138
139If you want to customize the `<GatewayDest>` element, you can pass any props,
140including `component` (which will allows you to specify a `tagName` or custom
141component), and they will be passed to the created element.
142
143```diff
144 export default class Application extends React.Component {
145 render() {
146 return (
147 <GatewayProvider>
148 <div>
149 {this.props.children}
150- <GatewayDest name="global"/>
151+ <GatewayDest name="global" component="section" className="global-gateway"/>
152 </div>
153 </GatewayProvider>
154 );
155 }
156 }
157```
158
159## How it works
160
161React Gateway works very differently than most React "portals" in order to work
162in server-side rendered React applications.
163
164It maintains an internal registry of "containers" and "children" which manages
165where things should be rendered.
166
167This registry is created by `<GatewayProvider>` and passed to `<Gateway>` and
168`<GatewayDest>` invisibly via React's `contextTypes`.
169
170Whenever a child or container is added or removed, React Gateway will
171update its internal registry and ensure things are properly rendered.
172
173## React Native example
174
175React Gateway does not directly depend on `react-dom`, so it works fine with
176React Native under one condition:
177
178**You must pass React Native component like `View` or similar to
179`component` prop of `<GatewayDest>`.**
180
181Because if you don't, `<GatewayDest>` will try to render `div` element, which
182is not available.
183
184```js
185import React from 'react';
186import { Text, View } from 'react-native';
187import {
188 Gateway,
189 GatewayDest,
190 GatewayProvider
191} from 'react-gateway';
192
193export default class Application extends React.Component {
194 render() {
195 return (
196 <GatewayProvider>
197 <View>
198 <Text>React Gateway Native Example</Text>
199 <View>
200 <Gateway into="one">
201 <Text>Text rendered elsewhere</Text>
202 </Gateway>
203 </View>
204 <GatewayDest name="one" component={View} />
205 </View>
206 </GatewayProvider>
207 );
208 }
209}
210```