Skip to content

Commit db18d80

Browse files
committed
added a new section with render props
1 parent fdd3845 commit db18d80

23 files changed

+235
-17
lines changed

README.md

+83-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ You should check Playground Project located in the `/playground` folder. It is a
3030
- [Stateless Components - SFC](#stateless-components---sfc)
3131
- [Stateful Components - Class](#stateful-components---class) 📝 __UPDATED__
3232
- [Generic Components](#generic-components)
33+
- [Render Props](#render-props) 🌟 __NEW__
3334
- [Higher-Order Components](#higher-order-components) 📝 __UPDATED__
3435
- [Redux Connected Components](#redux-connected-components)
3536
- [Redux](#redux)
@@ -176,7 +177,7 @@ export const SFCCounter: React.SFC<SFCCounterProps> = (props) => {
176177

177178
[⇧ back to top](#table-of-contents)
178179

179-
#### - spreading attributes [link](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes)
180+
#### - spread attributes [link](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes)
180181

181182
```tsx
182183
import * as React from 'react';
@@ -348,10 +349,88 @@ export class GenericList<T> extends React.Component<GenericListProps<T>, {}> {
348349

349350
---
350351

352+
## Render Props
353+
> https://reactjs.org/docs/render-props.html
354+
355+
#### - name provider
356+
> simple component using children as a render prop
357+
358+
```tsx
359+
import * as React from 'react';
360+
361+
interface NameProviderProps {
362+
children: (state: NameProviderState) => React.ReactNode;
363+
}
364+
365+
interface NameProviderState {
366+
name: string;
367+
}
368+
369+
export class NameProvider extends React.Component<NameProviderProps, NameProviderState> {
370+
state = {
371+
name: 'Piotr',
372+
};
373+
374+
render() {
375+
return this.props.children(this.state);
376+
}
377+
}
378+
379+
```
380+
381+
[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#nameprovider)
382+
383+
[⇧ back to top](#table-of-contents)
384+
385+
#### - mouse provider
386+
> `Mouse` component found in [Render Props React Docs](https://reactjs.org/docs/render-props.html#use-render-props-for-cross-cutting-concerns)
387+
388+
```tsx
389+
import * as React from 'react';
390+
391+
export interface MouseProviderProps {
392+
render: (state: MouseProviderState) => React.ReactNode;
393+
}
394+
395+
interface MouseProviderState {
396+
x: number;
397+
y: number;
398+
}
399+
400+
export class MouseProvider extends React.Component<MouseProviderProps, MouseProviderState> {
401+
state = { x: 0, y: 0 };
402+
403+
handleMouseMove = (event: React.MouseEvent<any>) => {
404+
this.setState({
405+
x: event.clientX,
406+
y: event.clientY,
407+
});
408+
}
409+
410+
render() {
411+
return (
412+
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove} >
413+
414+
{/*
415+
Instead of providing a static representation of what <Mouse> renders,
416+
use the `render` prop to dynamically determine what to render.
417+
*/}
418+
{this.props.render(this.state)}
419+
</div>
420+
);
421+
}
422+
}
423+
424+
```
425+
426+
[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#mouseprovider)
427+
428+
[⇧ back to top](#table-of-contents)
429+
430+
---
431+
351432
## Higher-Order Components
352-
- function that takes a component and returns a new component
353-
- a new component will infer Props interface from wrapped Component extended with Props of HOC
354-
- will filter out props specific to HOC, and the rest will be passed through to wrapped component
433+
> https://reactjs.org/docs/higher-order-components.html
355434

356435
#### - withState
357436
Adds state to a stateless counter

docs/build/0.78637d47.js renamed to docs/build/0.6e57cfb5.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/build/bundle.a71e23e0.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/build/bundle.b5df570e.js

-1
This file was deleted.

docs/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
</head>
88
<body>
99
<div id="app"></div>
10-
<script type="text/javascript" src="build/bundle.b5df570e.js"></script></body>
10+
<script type="text/javascript" src="build/bundle.a71e23e0.js"></script></body>
1111
</html>

docs/markdown/1_react.md

+25-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const element = <input onChange={handleChange} ...
6868

6969
[⇧ back to top](#table-of-contents)
7070

71-
#### - spreading attributes [link](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes)
71+
#### - spread attributes [link](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes)
7272

7373
::example='../../playground/src/components/sfc-spread-attributes.tsx'::
7474

@@ -112,10 +112,31 @@ const element = <input onChange={handleChange} ...
112112

113113
---
114114

115+
## Render Props
116+
> https://reactjs.org/docs/render-props.html
117+
118+
#### - name provider
119+
> simple component using children as a render prop
120+
121+
::example='../../playground/src/components/name-provider.tsx'::
122+
123+
[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#nameprovider)
124+
125+
[⇧ back to top](#table-of-contents)
126+
127+
#### - mouse provider
128+
> `Mouse` component found in [Render Props React Docs](https://reactjs.org/docs/render-props.html#use-render-props-for-cross-cutting-concerns)
129+
130+
::example='../../playground/src/components/mouse-provider.tsx'::
131+
132+
[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#mouseprovider)
133+
134+
[⇧ back to top](#table-of-contents)
135+
136+
---
137+
115138
## Higher-Order Components
116-
- function that takes a component and returns a new component
117-
- a new component will infer Props interface from wrapped Component extended with Props of HOC
118-
- will filter out props specific to HOC, and the rest will be passed through to wrapped component
139+
> https://reactjs.org/docs/higher-order-components.html
119140

120141
#### - withState
121142
Adds state to a stateless counter

docs/markdown/_toc.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Stateless Components - SFC](#stateless-components---sfc)
66
- [Stateful Components - Class](#stateful-components---class) 📝 __UPDATED__
77
- [Generic Components](#generic-components)
8+
- [Render Props](#render-props) 🌟 __NEW__
89
- [Higher-Order Components](#higher-order-components) 📝 __UPDATED__
910
- [Redux Connected Components](#redux-connected-components)
1011
- [Redux](#redux)

playground/src/components/generic-list.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Usage Demo:
77
const Demo = require('./generic-list.usage').default;
88
<Demo />
99
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--generic-list)

playground/src/components/generic-list.usage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ const users = [
1111

1212
export class UserList extends GenericList<IUser> { }
1313

14-
export default (() => (
14+
export default () => (
1515
<UserList
1616
items={users}
1717
itemRenderer={(item) => <div key={item.id}>{item.fullName}</div>}
1818
/>
19-
)) as React.SFC<{}>;
19+
);

playground/src/components/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ export * from './sfc-counter';
44
export * from './sfc-spread-attributes';
55
export * from './stateful-counter';
66
export * from './stateful-counter-with-default';
7+
export * from './name-provider';
8+
export * from './mouse-provider';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Usage:
2+
```jsx { "filePath": "./mouse-provider.usage.tsx" }
3+
```
4+
5+
Usage Demo:
6+
```jsx
7+
const Demo = require('./mouse-provider.usage').default;
8+
<Demo />
9+
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--mouse-provider)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as React from 'react';
2+
3+
export interface MouseProviderProps {
4+
render: (state: MouseProviderState) => React.ReactNode;
5+
}
6+
7+
interface MouseProviderState {
8+
x: number;
9+
y: number;
10+
}
11+
12+
export class MouseProvider extends React.Component<MouseProviderProps, MouseProviderState> {
13+
state = { x: 0, y: 0 };
14+
15+
handleMouseMove = (event: React.MouseEvent<any>) => {
16+
this.setState({
17+
x: event.clientX,
18+
y: event.clientY,
19+
});
20+
}
21+
22+
render() {
23+
return (
24+
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove} >
25+
26+
{/*
27+
Instead of providing a static representation of what <Mouse> renders,
28+
use the `render` prop to dynamically determine what to render.
29+
*/}
30+
{this.props.render(this.state)}
31+
</div>
32+
);
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as React from 'react';
2+
3+
import { MouseProvider } from './mouse-provider';
4+
5+
export default () => (
6+
<MouseProvider
7+
render={mouse => (
8+
<p>The mouse position is {mouse.x}, {mouse.y}</p>
9+
)}
10+
/>
11+
);
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Usage:
2+
```jsx { "filePath": "./name-provider.usage.tsx" }
3+
```
4+
5+
Usage Demo:
6+
```jsx
7+
const Demo = require('./name-provider.usage').default;
8+
<Demo />
9+
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--name-provider)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
3+
interface NameProviderProps {
4+
children: (state: NameProviderState) => React.ReactNode;
5+
}
6+
7+
interface NameProviderState {
8+
name: string;
9+
}
10+
11+
export class NameProvider extends React.Component<NameProviderProps, NameProviderState> {
12+
state = {
13+
name: 'Piotr',
14+
};
15+
16+
render() {
17+
return this.props.children(this.state);
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as React from 'react';
2+
3+
import { NameProvider } from './name-provider';
4+
5+
export default () => (
6+
<NameProvider>
7+
{({ name }) => (
8+
<div>{name}</div>
9+
)}
10+
</NameProvider>
11+
);

playground/src/components/sfc-counter.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Usage Demo:
77
const Demo = require('./sfc-counter.usage').default;
88
<Demo />
99
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--stateless-counter)

playground/src/components/sfc-spread-attributes.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Usage Demo:
77
const Demo = require('./sfc-spread-attributes.usage').default;
88
<Demo />
99
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--spread-attributes-link)

playground/src/components/sfc-spread-attributes.usage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import * as React from 'react';
22

33
import { SFCSpreadAttributes } from '@src/components';
44

5-
export default (() => (
5+
export default () => (
66
<SFCSpreadAttributes
77
className={'classy'}
88
style={{ backgroundColor: 'lightcyan' }}
99
>
1010
{`I'll spread every property you give me!`}
1111
</SFCSpreadAttributes>
12-
)) as React.SFC<{}>;
12+
);

playground/src/components/stateful-counter-with-default.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Usage Demo:
77
const Demo = require('./stateful-counter-with-default.usage').default;
88
<Demo />
99
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--with-default-props)

playground/src/components/stateful-counter.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Usage Demo:
77
const Demo = require('./stateful-counter.usage').default;
88
<Demo />
99
```
10+
11+
[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--stateful-counter)

playground/styleguide.config.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ module.exports = {
3232
{
3333
name: 'Generic Components',
3434
components: () => ([
35-
'./src/components/generic-list.tsx'
35+
'./src/components/generic-list.tsx',
36+
]),
37+
},
38+
{
39+
name: 'Render Props',
40+
components: () => ([
41+
'./src/components/name-provider.tsx',
42+
'./src/components/mouse-provider.tsx',
3643
]),
3744
},
3845
],

playground/tslint.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"typedef": [true,"parameter", "property-declaration"],
4747
"variable-name": [true, "ban-keywords", "check-format", "allow-pascal-case", "allow-leading-underscore"],
4848
// tslint-react
49+
"jsx-no-multiline-js": false,
4950
"jsx-no-lambda": false
5051
}
51-
}
52+
}

0 commit comments

Comments
 (0)