Repository: vasanthk/react-bits
Branch: master
Commit: 9c89659797f1
Files: 58
Total size: 109.7 KB
Directory structure:
gitextract_p1p5oxnm/
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.txt
├── READINGS.md
├── README.md
├── SUMMARY.md
├── anti-patterns/
│ ├── 01.props-in-initial-state.md
│ ├── 02.findDOMNode.md
│ ├── 03.mixins.md
│ ├── 04.setState-in-componentWillMount.md
│ ├── 05.mutating-state.md
│ ├── 06.using-indexes-as-key.md
│ ├── 07.spreading-props-dom.md
│ └── README.md
├── book.json
├── coding-style/
│ └── README.md
├── gotchas/
│ ├── 01.pure-render-checks.md
│ ├── 02.synthetic-events.md
│ └── README.md
├── package.json
├── patterns/
│ ├── 1.conditionals-in-jsx.md
│ ├── 10.passing-function-to-setState.md
│ ├── 11.decorators.md
│ ├── 12.feature-flags-using-redux.md
│ ├── 13.component-switch.md
│ ├── 14.reaching-into-a-component.md
│ ├── 15.list-components.md
│ ├── 16.format-text-via-component.md
│ ├── 17.react-fragments.md
│ ├── 18.share-tracking-logic.md
│ ├── 2.async-nature-of-setState.md
│ ├── 3.dependency-injection.md
│ ├── 4.context-wrapper.md
│ ├── 5.event-handlers.md
│ ├── 6.flux-pattern.md
│ ├── 7.one-way-data-flow.md
│ ├── 8.presentational-vs-container.md
│ └── 9.third-party-integration.md
├── perf-tips/
│ ├── 01.shouldComponentUpdate-check.md
│ ├── 02.pure-component.md
│ ├── 03.reselect.md
│ └── README.md
├── styling/
│ ├── 01.stateless-ui-components.md
│ ├── 02.styles-module.md
│ ├── 03.style-functions.md
│ ├── 04.using-npm-modules.md
│ ├── 05.base-component.md
│ ├── 06.layout-component.md
│ ├── 07.typography-component.md
│ ├── 08.HOC-for-styling.md
│ └── README.md
└── ux-variations/
├── 01.composing-variations.md
├── 02.toggle-ui-elements.md
├── 03.HOC-feature-toggles.md
├── 04.HOC-props-proxy.md
├── 05.wrapper-components.md
├── 06.display-order-variations.md
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
_book
node_modules
================================================
FILE: CONTRIBUTING.md
================================================
> Your contributions are heartily ♡ welcome. (✿◠‿◠)
================================================
FILE: LICENSE.txt
================================================
Creative Commons Attribution 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More_considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public licenses.
Notwithstanding, Creative Commons may elect to apply one of its public
licenses to material it publishes and in those instances will be
considered the "Licensor." Except for the limited purpose of indicating
that material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the public
licenses.
Creative Commons may be contacted at creativecommons.org.
================================================
FILE: READINGS.md
================================================
# Related Links
- [React in Patterns by krasimir](https://github.com/krasimir/react-in-patterns)
- [React Patterns by planningcenter](https://github.com/planningcenter/react-patterns)
- [reactpatterns.com](https://github.com/chantastic/reactpatterns.com)
- [10 React Mini-patterns](https://hackernoon.com/10-react-mini-patterns-c1da92f068c5)
================================================
FILE: README.md
================================================
# [React Bits](https://vasanthk.gitbooks.io/react-bits)
A compilation of React Patterns, techniques, tips and tricks.
**Gitbook format**: https://vasanthk.gitbooks.io/react-bits
**Github repo**: https://github.com/vasanthk/react-bits
> Your contributions are heartily ♡ welcome. (✿◠‿◠)
> **Translations by community:**
> - 中文版 (Chinese): [react-bits-cn](https://github.com/hateonion/react-bits-CN)
> - 한국어 (Korean): [react-bits-ko](https://github.com/rayleighko/react-bits-ko)
- Design Patterns and Techniques
- [Conditional in JSX](./patterns/1.conditionals-in-jsx.md)
- [Async Nature Of setState()](./patterns/2.async-nature-of-setState.md)
- [Dependency Injection](./patterns/3.dependency-injection.md)
- [Context Wrapper](./patterns/4.context-wrapper.md)
- [Event Handlers](./patterns/5.event-handlers.md)
- [Flux Pattern](./patterns/6.flux-pattern.md)
- [One Way Data Flow](./patterns/7.one-way-data-flow.md)
- [Presentational vs Container](./patterns/8.presentational-vs-container.md)
- [Third Party Integration](./patterns/9.third-party-integration.md)
- [Passing Function To setState()](./patterns/10.passing-function-to-setState.md)
- [Decorators](./patterns/11.decorators.md)
- [Feature Flags](./patterns/12.feature-flags-using-redux.md)
- [Component Switch](./patterns/13.component-switch.md)
- [Reaching Into A Component](./patterns/14.reaching-into-a-component.md)
- [List Components](./patterns/15.list-components.md)
- [Format Text via Component](./patterns/16.format-text-via-component.md)
- [React Fragments](./patterns/17.react-fragments.md)
- [Share Tracking Logic](./patterns/18.share-tracking-logic.md)
- Anti-Patterns
- [Introduction](./anti-patterns/README.md)
- [Props In Initial State](./anti-patterns/01.props-in-initial-state.md)
- [findDOMNode()](./anti-patterns/02.findDOMNode.md)
- [Mixins](./anti-patterns/03.mixins.md)
- [setState() in componentWillMount()](./anti-patterns/04.setState-in-componentWillMount.md)
- [Mutating State](./anti-patterns/05.mutating-state.md)
- [Using Indexes as Key](./anti-patterns/06.using-indexes-as-key.md)
- [Spreading Props on DOM elements](./anti-patterns/07.spreading-props-dom.md)
- Handling UX Variations
- [Introduction](./ux-variations/README.md)
- [Composing UX Variations](./ux-variations/01.composing-variations.md)
- [Toggle UI Elements](./ux-variations/02.toggle-ui-elements.md)
- [HOC for Feature Toggles](./ux-variations/03.HOC-feature-toggles.md)
- [HOC props proxy](./ux-variations/04.HOC-props-proxy.md)
- [Wrapper Components](./ux-variations/05.wrapper-components.md)
- [Display Order Variations](./ux-variations/06.display-order-variations.md)
- Perf Tips
- [Introduction](./perf-tips/README.md)
- [shouldComponentUpdate() check](./perf-tips/01.shouldComponentUpdate-check.md)
- [Using Pure Components](./perf-tips/02.pure-component.md)
- [Using reselect](./perf-tips/03.reselect.md)
- Styling
- [Introduction](./styling/README.md)
- [Stateless UI Components](./styling/01.stateless-ui-components.md)
- [Styles Module](./styling/02.styles-module.md)
- [Style Functions](./styling/03.style-functions.md)
- [NPM Modules](./styling/04.using-npm-modules.md)
- [Base Component](./styling/05.base-component.md)
- [Layout Component](./styling/06.layout-component.md)
- [Typography Component](./styling/07.typography-component.md)
- [HOC for Styling](./styling/08.HOC-for-styling.md)
- Gotchas
- [Introduction](./gotchas/README.md)
- [Pure render checks](./gotchas/01.pure-render-checks.md)
- [Synthetic Events](./gotchas/02.synthetic-events.md)
- [Related Links](./READINGS.md)
================================================
FILE: SUMMARY.md
================================================
# React Bits
✨ React patterns, techniques, tips and tricks ✨
- Design Patterns and Techniques
- [Conditional in JSX](./patterns/18.conditionals-in-jsx.md)
- [Async Nature Of setState()](./patterns/19.async-nature-of-setState.md)
- [Dependency Injection](./patterns/20.dependency-injection.md)
- [Context Wrapper](./patterns/21.context-wrapper.md)
- [Event Handlers](./patterns/22.event-handlers.md)
- [Flux Pattern](./patterns/23.flux-pattern.md)
- [One Way Data Flow](./patterns/24.one-way-data-flow.md)
- [Presentational vs Container](./patterns/25.presentational-vs-container.md)
- [Third Party Integration](./patterns/26.third-party-integration.md)
- [Passing Function To setState()](./patterns/27.passing-function-to-setState.md)
- [Decorators](./patterns/28.decorators.md)
- [Feature Flags](./patterns/29.feature-flags-using-redux.md)
- [Component Switch](./patterns/30.component-switch.md)
- [Reaching Into A Component](./patterns/31.reaching-into-a-component.md)
- [List Components](./patterns/32.list-components.md)
- [Format Text via Component](./patterns/33.format-text-via-component.md)
- [Share Tracking Logic](./patterns/34.share-tracking-logic.md)
- Anti-Patterns
- [Introduction](./anti-patterns/README.md)
- [Props In Initial State](./anti-patterns/01.props-in-initial-state.md)
- [findDOMNode()](./anti-patterns/02.findDOMNode.md)
- [Mixins](./anti-patterns/03.mixins.md)
- [setState() in componentWillMount()](./anti-patterns/04.setState-in-componentWillMount.md)
- [Mutating State](./anti-patterns/05.mutating-state.md)
- [Using Indexes as Key](./anti-patterns/06.using-indexes-as-key.md)
- [Spreading Props on DOM elements](./anti-patterns/07.spreading-props-dom.md)
- Handling UX Variations
- [Introduction](./ux-variations/README.md)
- [Composing UX Variations](./ux-variations/01.composing-variations.md)
- [Toggle UI Elements](./ux-variations/02.toggle-ui-elements.md)
- [HOC for Feature Toggles](./ux-variations/03.HOC-feature-toggles.md)
- [HOC props proxy](./ux-variations/04.HOC-props-proxy.md)
- [Wrapper Components](./ux-variations/05.wrapper-components.md)
- [Display Order Variations](./ux-variations/06.display-order-variations.md)
- Perf Tips
- [Introduction](./perf-tips/README.md)
- [shouldComponentUpdate() check](./perf-tips/01.shouldComponentUpdate-check.md)
- [Using Pure Components](./perf-tips/02.pure-component.md)
- [Using reselect](./perf-tips/03.reselect.md)
- Styling
- [Introduction](./styling/README.md)
- [Stateless UI Components](./styling/01.stateless-ui-components.md)
- [Styles Module](./styling/02.styles-module.md)
- [Style Functions](./styling/03.style-functions.md)
- [npm Modules](./styling/04.using-npm-modules.md)
- [Base Component](./styling/05.base-component.md)
- [Layout Component](./styling/06.layout-component.md)
- [Typography Component](./styling/07.typography-component.md)
- [HOC for Styling](./styling/08.HOC-for-styling.md)
- Gotchas
- [Introduction](./gotchas/README.md)
- [Pure render checks](./gotchas/01.pure-render-checks.md)
- [Synthetic Events](./gotchas/02.synthetic-events.md)
- [Related Links](./READINGS.md)
================================================
FILE: anti-patterns/01.props-in-initial-state.md
================================================
# Props in Initial State
From docs:
> Using props to generate state in getInitialState often leads to duplication of “source of truth”, i.e. where the real data is.
> This is because getInitialState is only invoked when the component is first created.
The danger is that if the props on the component are changed without the component being ‘refreshed’,
the new prop value will never be displayed because the constructor function (or getInitialState) will never update the current state of the component.
The initialization of state from props only runs when the component is first created.
#### Bad
```javascript
class SampleComponent extends Component {
// constructor function (or getInitialState)
constructor(props) {
super(props);
this.state = {
flag: false,
inputVal: props.inputValue
};
}
render() {
return <div>{this.state.inputVal && <AnotherComponent/>}</div>
}
}
```
#### Good
```javascript
class SampleComponent extends Component {
// constructor function (or getInitialState)
constructor(props) {
super(props);
this.state = {
flag: false
};
}
render() {
return <div>{this.props.inputValue && <AnotherComponent/>}</div>
}
}
```
### Related links:
- [React Anti-Patterns: Props in Initial State](https://medium.com/@justintulk/react-anti-patterns-props-in-initial-state-28687846cc2e)
- [Why is passing the component initial state a prop an anti-pattern?](http://stackoverflow.com/questions/28785106/reactjs-why-is-passing-the-component-initial-state-a-prop-an-anti-pattern)
================================================
FILE: anti-patterns/02.findDOMNode.md
================================================
# Refs over findDOMNode()
Use callback refs over findDOMNode()
Note:
React also supports using a string (instead of a callback) as a ref prop on any component, although this approach is mostly legacy at this point.
- [More about refs](https://reactjs.org/docs/refs-and-the-dom.html)
- [Why ref-string is legacy?](http://stackoverflow.com/questions/37468913/why-ref-string-is-legacy)
##### findDOMNode(this)
###### Before:
```javascript
class MyComponent extends Component {
componentDidMount() {
findDOMNode(this).scrollIntoView();
}
render() {
return <div />
}
}
```
###### After
```javascript
class MyComponent extends Component {
componentDidMount() {
this.node.scrollIntoView();
}
render() {
return <div ref={node => this.node = node}/>
}
}
```
##### findDOMNode(stringDOMRef)
###### Before
```javascript
class MyComponent extends Component {
componentDidMount() {
findDOMNode(this.refs.something).scrollIntoView();
}
render() {
return (
<div>
<div ref='something'/>
</div>
)
}
}
```
###### After
```javascript
class MyComponent extends Component {
componentDidMount() {
this.something.scrollIntoView();
}
render() {
return (
<div>
<div ref={node => this.something = node}/>
</div>
)
}
}
```
##### findDOMNode(childComponentStringRef)
###### Before:
```javascript
class Field extends Component {
render() {
return <input type='text'/>
}
}
class MyComponent extends Component {
componentDidMount() {
findDOMNode(this.refs.myInput).focus();
}
render() {
return (
<div>
Hello,
<Field ref='myInput'/>
</div>
)
}
}
```
###### After
```javascript
class Field extends Component {
render() {
return (
<input type='text' ref={this.props.inputRef}/>
)
}
}
class MyComponent extends Component {
componentDidMount() {
this.inputNode.focus();
}
render() {
return (
<div>
Hello,
<Field inputRef={node => this.inputNode = node}/>
</div>
)
}
}
```
### Related links:
- [ESLint Rule proposal: warn against using findDOMNode()](https://github.com/yannickcr/eslint-plugin-react/issues/678#issue-165177220)
- [Refs and the DOM](https://reactjs.org/docs/refs-and-the-dom.html)
================================================
FILE: anti-patterns/03.mixins.md
================================================
# Use Higher order components over Mixins
#### Simple Example
```javascript
// With Mixin
var WithLink = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function () {
return {message: 'Hello!'};
},
render: function () {
return <input type="text" valueLink={this.linkState('message')}/>;
}
});
// Move logic to a HOC
var WithLink = React.createClass({
getInitialState: function () {
return {message: 'Hello!'};
},
render: function () {
return <input type="text" valueLink={LinkState(this,'message')}/>;
}
});
```
#### Detailed Example
```javascript
// With Mixin
var CarDataMixin = {
componentDidMount: {
// fetch car data and
// call this.setState({carData: fetchedData}),
// once data has been (asynchronously) fetched
}
};
var FirstView = React.createClass({
mixins: [CarDataMixin],
render: function () {
return (
<div>
<AvgSellingPricesByYear country="US" dataset={this.state.carData}/>
<AvgSellingPricesByYear country="UK" dataset={this.state.carData}/>
<AvgSellingPricesByYear country="FI" dataset={this.state.carData}/>
</div>
)
}
});
// With HOC
var bindToCarData = function (Component) {
return React.createClass({
componentDidMount: {
// fetch car data and
// call this.setState({carData: fetchedData}),
// once data has been (asynchronously) fetched
},
render: function () {
return <Component carData={ this.state.carData }/>
}
});
};
// Then wrap your component when you define it.
var FirstView = bindToCarData(React.createClass({
render: function () {
return (
<div>
<AvgSellingPricesByYear country="US" dataset={this.props.carData}/>
<AvgSellingPricesByYear country="UK" dataset={this.props.carData}/>
<AvgSellingPricesByYear country="FI" dataset={this.props.carData}/>
</div>
)
}
}));
```
### Related links:
- [Mixins are dead - Long live higher ordercomponents](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750)
- [Mixins are considered harmful](https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html)
- [Stackoverflow: Using mixins vs components for code reuse](http://stackoverflow.com/questions/21854938/using-mixins-vs-components-for-code-reuse-in-facebook-react)
- [Stackoverflow: Composition instead of mixins in React](http://stackoverflow.com/questions/30845561/how-to-solve-this-using-composition-instead-of-mixins-in-react)
================================================
FILE: anti-patterns/04.setState-in-componentWillMount.md
================================================
# setState() in componentWillMount()
Avoid async initialization in ``componentWillMount()``
``componentWillMount()`` is invoked immediately before mounting occurs.
It is called before ``render()``, therefore setting state in this method will not trigger a re-render.
Avoid introducing any side-effects or subscriptions in this method.
Make async calls for component initialization in ``componentDidMount`` instead of ``componentWillMount``
```javascript
function componentDidMount() {
axios.get(`api/messages`)
.then((result) => {
const messages = result.data
console.log("COMPONENT WILL Mount messages : ", messages);
this.setState({
messages: [...messages.content]
})
})
}
```
================================================
FILE: anti-patterns/05.mutating-state.md
================================================
# Mutating State without setState()
- Causes state changes without making component re-render.
- Whenever setState gets called in future, the mutated state gets applied.
#### Bad
``` javascript
class SampleComponent extends Component {
constructor(props) {
super(props);
this.state = {
items: ['foo', 'bar']
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// BAD: We mutate state here
this.state.items.push('lorem');
this.setState({
items: this.state.items
});
}
render() {
return (
<div>
{this.state.items.length}
<button onClick={this.handleClick}>+</button>
</div>
)
}
}
```
#### Good
``` javascript
class SampleComponent extends Component {
constructor(props) {
super(props);
this.state = {
items: ['foo', 'bar']
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// We update using setState() - concat return new array after appending new item.
this.setState(prevState => ({
items: prevState.items.concat('lorem')
}));
}
render() {
return (
<div>
{this.state.items.length}
<button onClick={this.handleClick}>+</button>
</div>
)
}
}
```
### Related links:
[React Design Patterns and best practices by Michele Bertoli.](https://github.com/MicheleBertoli/react-design-patterns-and-best-practices)
================================================
FILE: anti-patterns/06.using-indexes-as-key.md
================================================
# Using indexes as keys
Keys should be stable, predictable, and unique so that React can keep track of elements.
#### Bad
In this snippet each element's key will be based on ordering, rather than tied to the data that is being represented. This limits the optimizations that React can do.
```javascript
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
```
#### Good
Assuming `todo.id` is unique to this list and stable, React would be able to reorder elements without needing to reevaluate them as much.
```javascript
{todos.map((todo) =>
<Todo {...todo}
key={todo.id} />
)}
```
### @Reference:
- [React docs](https://reactjs.org/docs/reconciliation.html#tradeoffs)
- [Lin Clark's code cartoon](https://youtu.be/-t8eOoRsJ7M?t=981)
================================================
FILE: anti-patterns/07.spreading-props-dom.md
================================================
# Spreading props on DOM elements
When we spread props we run into the risk of adding unknown HTML attributes, which is a bad practice.
#### Bad
This will try to add the unknown HTML attribute `flag` to the DOM element.
```javascript
const Sample = () => (<Spread flag={true} className="content"/>);
const Spread = (props) => (<div {...props}>Test</div>);
```
#### Good
By creating props specifically for DOM attribute, we can safely spread.
```javascript
const Sample = () => (<Spread flag={true} domProps={{className: "content"}}/>);
const Spread = (props) => (<div {...props.domProps}>Test</div>);
```
Or alternatively we can use prop destructuring with `...rest`:
```javascript
const Sample = () => (<Spread flag={true} className="content"/>);
const Spread = ({ flag, ...domProps }) => (<div {...domProps}>Test</div>);
```
*Note*
In [scenarios](https://github.com/vasanthk/react-bits/issues/34) where you use a [PureComponent](../perf-tips/02.pure-component.md), when an update happens it re-renders the component even if `domProps` did not change. This is because PureComponent only [shallowly compares](https://reactjs.org/docs/react-api.html#reactpurecomponent) the objects.
### Related links:
- [React Design Patterns and best practices by Michele Bertoli.](https://github.com/MicheleBertoli/react-design-patterns-and-best-practices)
- [In React, children are just props: Kent C. Dodds' Tweet](https://twitter.com/kentcdodds/status/851406788549369856)
================================================
FILE: anti-patterns/README.md
================================================
# Anti-patterns
Familiarizing ourselves with common anti-patterns will help us understand how React works and describe useful forms of refactoring our code.
================================================
FILE: book.json
================================================
{
"gitbook": ">3.0.0",
"plugins": ["edit-link"],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/vasanthk/react-bits/blob/master",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/vasanthk/react-bits/"
}
}
}
================================================
FILE: coding-style/README.md
================================================
# Coding Style
**Disclaimer:**
This section is purely to familiarize oneself with different coding styles out there. It is not a set of coding standards or conventions!
================================================
FILE: gotchas/01.pure-render-checks.md
================================================
# Pure Render Checks
In order to preserve performance one needs to consider the creation of new entities in the render method.
Pure render?
With React.js pure render I mean components that implement the shouldComponentUpdate method with shallow equality checks.
Examples of this are the React.PureComponent, PureRenderMixin, recompose/pure and many others.
#### Case 1
##### Bad
```javascript
class Table extends PureComponent {
render() {
return (
<div>
{this.props.items.map(i =>
<Cell data={i} options={this.props.options || []}/>
)}
</div>
);
}
}
```
**The issue is with ``{this.props.options || []}`` - it caused all the cells to be re-rendered even for a single cell change. Why?**
You see the options array was passed deep down in the Cell elements. Normally this would not be an issue.
The other Cell elements would not be re-rendered because they can do the cheap shallow equality check and
skip the render entirely but in this case the options prop was null and the default array was used.
As you should know the array literal is the same as new Array() which creates a new array instance.
This completely destroyed every pure render optimization inside the Cell elements.
In Javascript different instances have different identities and thus the shallow equality check always
produces false and tells React to re-render the components.
##### Good
```javascript
const defaultval = []; // <--- The fix (defaultProps could also have been used).
class Table extends PureComponent {
render() {
return (
<div>
{this.props.items.map(i =>
<Cell data={i} options={this.props.options || defaultval}/>
)}
</div>
);
}
}
```
#### Case 2
Similar issue with using functions in render() as well
##### BAD
```javascript
class App extends PureComponent {
render() {
return <MyInput
onChange={e => this.props.update(e.target.value)}/>;
}
}
```
##### Bad again
```javascript
class App extends PureComponent {
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update.bind(this)}/>;
}
}
```
^^In both cases a new function is created with a new identity. Just like with the array literal.
We need to bind the function early
##### Good
```javascript
class App extends PureComponent {
constructor(props) {
super(props);
this.update = this.update.bind(this);
}
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update}/>;
}
}
```
##### Bad
```javascript
class Component extends React.Component {
state = {clicked: false};
onClick() {
this.setState({clicked: true})
}
render() {
// Options object created each render if not set
const options = this.props.options || {test: 1};
return <Something
options={options}
// New function created each render
onClick={this.onClick.bind(this)}
// New function & closure created each render
onTouchTap={(event) => this.onClick(event)
/>
}
}
```
##### Good
```javascript
class Component extends React.Component {
state = {clicked: false};
options = {test: 1};
onClick = () => {
this.setState({clicked: true})
};
render() {
// Options object created once
const options = this.props.options || this.options;
return <Something
options={options}
onClick={this.onClick} // Function created once, bound once
onTouchTap={this.onClick} // Function created once, bound once
/>
}
}
```
### Related links:
- https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f
- https://github.com/nfour/js-structures/blob/master/guides/react-anti-patterns.md#pure-render-immutability
- [Optimizing React Rendering](https://flexport.engineering/optimizing-react-rendering-part-1-9634469dca02)
================================================
FILE: gotchas/02.synthetic-events.md
================================================
# Synthetic events in React
Inside React event handlers, the event object is wrapped in a SyntheticEvent object.
These objects are pooled, which means that the objects received at an event handler will be reused for other events to increase performance.
This also means that accessing the event object’s properties asynchronously will be impossible since the event’s properties have been reset due to reuse.
The following piece of code will log null because event has been reused inside the SyntheticEvent pool:
```javascript
function handleClick(event) {
setTimeout(function () {
console.log(event.target.name);
}, 1000);
}
```
To avoid this you need to store the event’s property you are interested in inside its own binding:
```javascript
function handleClick(event) {
let name = event.target.name;
setTimeout(function () {
console.log(name);
}, 1000);
}
```
### Related links:
- [React/Redux: Best practices & gotchas](https://medium.com/nick-parsons/react-redux-best-practices-gotchas-56cf61c1c415)
- [React events in depth w/ Kent C. Dodds, Ben Alpert, & Dan Abramov](https://www.youtube.com/watch?v=dRo_egw7tBc)
================================================
FILE: gotchas/README.md
================================================
# Gotchas
React is intuitive for the most part, but there are quite a few stumbling points which might catch you by surprise. We'll discuss more on them here.
## Articles
[React Gotchas](https://daveceddia.com/react-gotchas/)
[Top 5 React Gotchas](http://joelgriffith.net/top-5-react-gotchas/)
================================================
FILE: package.json
================================================
{
"name": "react-bits",
"version": "1.0.0",
"repository": "https://github.com/vasanthk/react-bits.git",
"author": "",
"license": "MIT",
"scripts": {
"docs": "gitbook serve"
}
}
================================================
FILE: patterns/1.conditionals-in-jsx.md
================================================
# Conditionals in JSX
Instead of
```javascript
const sampleComponent = () => {
return isTrue ? <p>True!</p> : null
};
```
Use short-circuit evaluation
```javascript
const sampleComponent = () => {
return isTrue && <p>True!</p>
};
```
For Complex scenarios with too many ternaries:
```javascript
// Y soo many ternary??? :-/
const sampleComponent = () => {
return (
<div>
{flag && flag2 && !flag3
? flag4
? <p>Blah</p>
: flag5
? <p>Meh</p>
: <p>Herp</p>
: <p>Derp</p>
}
</div>
)
};
```
- Best approach: Move logic to sub-components
- Alternate hacky approach: Use IIFE
There are some libraries that solve this problem (JSX-Control Statements), but rather than introduce another dependency
use an [IIFE](http://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript) and return values by using if-else statement inside
```javascript
const sampleComponent = () => {
return (
<div>
{
(() => {
if (flag && flag2 && !flag3) {
if (flag4) {
return <p>Blah</p>
} else if (flag5) {
return <p>Meh</p>
} else {
return <p>Herp</p>
}
} else {
return <p>Derp</p>
}
})()
}
</div>
)
};
```
With an appropiate [transpiler](https://babeljs.io/docs/plugins/transform-do-expressions/) you can take advantage of the upcoming [do expression](https://github.com/tc39/proposal-do-expressions) which is currently on [stage-1](https://github.com/tc39/proposal-do-expressions)
```javascript
const sampleComponent = () => {
return (
<div>
{
do {
if (flag && flag2 && !flag3) {
if (flag4) {
return <p>Blah</p>;
} else if (flag5) {
return <p>Meh</p>;
} else {
return <p>Herp</p>;
}
} else {
return <p>Derp</p>;
}
}
}
</div>
)
};
```
Or alternatively simply use early returns
```javascript
const sampleComponent = () => {
const basicCondition = flag && flag2 && !flag3;
if (!basicCondition) return <p>Derp</p>;
if (flag4) return <p>Blah</p>;
if (flag5) return <p>Meh</p>;
return <p>Herp</p>
}
```
### Related links:
- https://engineering.musefind.com/our-best-practices-for-writing-react-components-dec3eb5c3fc8
- [Conditional rendering](https://reactjs.org/docs/conditional-rendering.html)
================================================
FILE: patterns/10.passing-function-to-setState.md
================================================
# Passing a function to setState
Here’s the dirty secret about setState — it’s actually asynchronous.
React batches state changes for performance reasons, so the state may not change immediately after setState is called.
That means you should not rely on the current state when calling setState — since you can’t be sure what that state will be!
Here’s the solution — pass a function to setState, with the previous state as an argument.
Doing so avoids issues with the user getting the old state value on access (due to the asynchrony of setState)
#### Problem
```javascript
// assuming this.state.count === 0
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
// this.state.count === 1, not 3
```
#### Solution
```javascript
this.setState((prevState, props) => ({
count: prevState.count + props.increment
}));
```
#### Variations
```javascript
// Passing object
this.setState({ expanded: !this.state.expanded });
// Passing function
this.setState(prevState => ({ expanded: !prevState.expanded }));
```
### Related links:
- [setState() Gate](https://medium.com/javascript-scene/setstate-gate-abc10a9b2d82)
- [Do I need to use setState(function) overload in this case?](http://stackoverflow.com/questions/43428456/do-i-need-to-use-setstatefunction-overload-in-this-case/43440790#43440790)
- [Functional setState is the future of React](https://medium.freecodecamp.com/functional-setstate-is-the-future-of-react-374f30401b6b)
================================================
FILE: patterns/11.decorators.md
================================================
# Decorators
Decorators (*supported by Babel, in Stage 2 proposal as of 03/17*)
If you’re using something like mobx, you can decorate your class components — which is the same as passing the component into a function.
Decorators are flexible and readable way of modifying component functionality.
Non-decorators approach
```javascript
class ProfileContainer extends Component {
// Component code
}
export default observer(ProfileContainer)
```
With decorators
```javascript
@observer
export default class ProfileContainer extends Component {
// Component code
}
```
### Article:
- [Enhancing React components with Decorators](https://medium.com/@gigobyte/enhancing-react-components-with-decorators-441320e8606a)
### Related:
- [Decorators != higher ordered components](https://twitter.com/dan_abramov/status/628202050946514944)
- [React Decorator example - Module](https://github.com/gigobyte/react-document-title-decorator)
- [What is the use of Connect(decorator in react-redux)](http://stackoverflow.com/questions/36553814/what-is-the-use-of-connect-decorator-in-react-redux)
- [Decorators with React Components](http://stackoverflow.com/questions/36286384/decorators-with-react-components)
- [Exploring ES7 decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.8cbzw5wcl)
- [Understanding Decorators](https://survivejs.com/react/appendices/understanding-decorators/)
================================================
FILE: patterns/12.feature-flags-using-redux.md
================================================
# Feature Flags
Enabling Feature flags in React using Redux
```javascript
// createFeatureFlaggedContainer.js
import React from 'react';
import { connect } from 'react-redux';
import { isFeatureEnabled } from './reducers'
export default function createFeatureFlaggedContainer({
featureName,
enabledComponent,
disabledComponent
}) {
function FeatureFlaggedContainer({ isEnabled, ...props }) {
const Component = isEnabled ? enabledComponent : disabledComponent;
if (Component) {
return <Component {...props} />;
}
// `disabledComponent` is optional property
return null;
}
// Having `displayName` is very useful for debugging.
FeatureFlaggedContainer.displayName = `FeatureFlaggedContainer(${ featureName })`;
return connect((store) => {
isEnabled: isFeatureEnabled(store, featureName)
})(FeatureFlaggedContainer);
}
```
```javascript
// EnabledFeature.js
import { connect } from 'react-redux';
import { isFeatureEnabled } from './reducers'
function EnabledFeature({ isEnabled, children }) {
if (isEnabled) {
return children;
}
return null;
}
export default connect((store, { name }) => {
isEnabled: isFeatureEnabled(store, name)
})(EnabledFeature);
```
```javascript
// featureEnabled.js
import createFeatureFlaggedContainer from './createFeatureFlaggedContainer'
// Decorator for "Page" components.
// usage: enabledFeature('unicorns')(UnicornsPage);
export default function enabledFeature(featureName) {
return (Component) => {
return createFeatureFlaggedContainer({
featureName,
enabledComponent: Component,
disabledComponent: PageNotFound, // 404 page or something similar
});
};
};
```
```javascript
// features.js
// This is quite simple reducer, containing only an array of features.
// You can attach this data to a `currentUser` or similar reducer.
// `BOOTSTAP` is global action, which contains the initial data for a page
// Features access usually don't change during user usage of a page
const BOOTSTAP = 'features/receive';
export default function featuresReducer(state, { type, payload }) {
if (type === BOOTSTAP) {
return payload.features || [];
}
return state || [];
}
export function isFeatureEnabled(features, featureName) {
return features.indexOf(featureName) !== -1;
}
```
```javascript
// reducers.js
// This is your main reducer.js file
import { combineReducers } from 'redux';
import features, { isFeatureEnabled as isFeatureEnabledSelector } from './features';
// ...other reducers
export default combineReducers({
features
// ...other reducers
});
// This is the important part, access to `features` reducer should only happens
// via this selector.
// Then you can always change where/how the features are stored.
export function isFeatureEnabled({ features }, featureName) {
return isFeatureEnabledSelector(features, featureName);
}
```
### Related links:
- [Feature flags in React](http://blog.rstankov.com/feature-flags-in-react/)
- [Gist](https://gist.github.com/RStankov/0e764f27daf38f2fcd81b82360334528)
================================================
FILE: patterns/13.component-switch.md
================================================
# The switching component
A switching component is a component that renders one of many components.
Use an object to map prop values to components
```javascript
import HomePage from './HomePage.jsx';
import AboutPage from './AboutPage.jsx';
import UserPage from './UserPage.jsx';
import FourOhFourPage from './FourOhFourPage.jsx';
const PAGES = {
home: HomePage,
about: AboutPage,
user: UserPage
};
const Page = (props) => {
const Handler = PAGES[props.page] || FourOhFourPage;
return <Handler {...props} />
};
// The keys of the PAGES object can be used in the prop types to catch dev-time errors.
Page.propTypes = {
page: PropTypes.oneOf(Object.keys(PAGES)).isRequired
};
```
### Related links:
- https://hackernoon.com/10-react-mini-patterns-c1da92f068c5
================================================
FILE: patterns/14.reaching-into-a-component.md
================================================
# Reaching into a Component
Accessing a component from the parent.
eg. Autofocus an input (controlled by parent component)
#### Child Component
An input component with a focus() method that focuses the HTML element
```javascript
class Input extends Component {
focus() {
this.el.focus();
}
render() {
return (
<input
ref={el=> { this.el = el; }}
/>
);
}
}
```
#### Parent Component
In the parent component, we can get a reference to the Input component and call its focus() method.
```javascript
class SignInModal extends Component {
componentDidMount() {
// Note that when you use ref on a component, it’s a reference to
// the component (not the underlying element), so you have access to its methods.
this.InputComponent.focus();
}
render() {
return (
<div>
<label>User name:</label>
<Input
ref={comp => { this.InputComponent = comp; }}
/>
</div>
)
}
}
```
### Reference:
- https://hackernoon.com/10-react-mini-patterns-c1da92f068c5
================================================
FILE: patterns/15.list-components.md
================================================
# Lists Components
Lists and other things that are almost components
Instead of making a separate component for lists I can then generate the results like:
```javascript
// renderSearchSuggestion() behaves as a pseudo SearchSuggestion component
// keep it self contained and it should be easy to extract later if needed
const renderSearchSuggestion = listItem => (
<li key={listItem.id}>{listItem.name} {listItem.id}</li>
);
const SearchSuggestions = (props) => {
return (
<ul>
{props.listItems.map(renderSearchSuggestion)}
</ul>
);
};
```
If things get more complex or you want to use this component elsewhere,
you should be able to copy/paste the code out into a new component.
Don’t prematurely componentize.
### Related links:
- https://hackernoon.com/10-react-mini-patterns-c1da92f068c5
================================================
FILE: patterns/16.format-text-via-component.md
================================================
# Components for formatting text
Instead of formatting text by calling helper functions inside render, we can create a separate component that
handles this.
#### With Component
Render function is lot cleaner to comprehend as it is just simple component composition.
```javascript
const Price = (props) => {
// toLocaleString is not React specific syntax - it is a native JavaScript function used fo formatting
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
const price = props.children.toLocaleString('en', {
style: props.showSymbol ? 'currency' : undefined,
currency: props.showSymbol ? 'USD' : undefined,
maximumFractionDigits: props.showDecimals ? 2 : 0
});
return <span className={props.className}>{price}</span>
};
Price.propTypes = {
className: PropTypes.string,
children: PropTypes.number,
showDecimals: PropTypes.bool,
showSymbol: PropTypes.bool
};
Price.defaultProps = {
children: 0,
showDecimals: true,
showSymbol: true,
};
const Page = () => {
const lambPrice = 1234.567;
const jetPrice = 999999.99;
const bootPrice = 34.567;
return (
<div>
<p>One lamb is <Price className="expensive">{lambPrice}</Price></p>
<p>One jet is <Price showDecimals={false}>{jetPrice}</Price></p>
<p>Those gumboots will set ya back
<Price
showDecimals={false}
showSymbol={false}>
{bootPrice}
</Price>
bucks.
</p>
</div>
);
};
```
#### Without Component
Less code: But render looks less clean. (Debatable, yeah I understand)
```javascript
function numberToPrice(num, options = {}) {
const showSymbol = options.showSymbol !== false;
const showDecimals = options.showDecimals !== false;
return num.toLocaleString('en', {
style: showSymbol ? 'currency' : undefined,
currency: showSymbol ? 'USD' : undefined,
maximumFractionDigits: showDecimals ? 2 : 0
});
}
const Page = () => {
const lambPrice = 1234.567;
const jetPrice = 999999.99;
const bootPrice = 34.567;
return (
<div>
<p>One lamb is <span className="expensive">{numberToPrice(lambPrice)}</span></p>
<p>One jet is {numberToPrice(jetPrice, { showDecimals: false })}</p>
<p>Those gumboots will set ya back
{numberToPrice(bootPrice, { showDecimals: false, showSymbol: false })}
bucks.</p>
</div>
);
};
```
### Reference:
- [10 React Mini Patterns](https://hackernoon.com/10-react-mini-patterns-c1da92f068c5)
================================================
FILE: patterns/17.react-fragments.md
================================================
# React Fragments
React fragments are used whenever a component needs returned with multiple children.
Specifically, fragments are useful when I don't want to clutter the DOM with unnecessary `<div>` tags that are used purely to wrap children in a React render method.
For example, React fragments are commonly used to render list items:
```javascript
render() {
return (
<React.Fragment>
<td>Table Cell 1</td>
<td>Table Cell 2</td>
</React.Fragment>
);
}
```
This solves the issue of breaking the DOM HTML table specifications by not adding unnecessary `<div>` elements around `<td>` elements.
Do keep in mind, if it is a list being rendered, React does still throw warnings when children don't have the `key={}` prop.
### Related links:
- https://reactjs.org/docs/fragments.html
================================================
FILE: patterns/18.share-tracking-logic.md
================================================
# Share Tracking Logic
Using HOC to share tracking logic across various UX components
eg. Adding analytics tracking across various components.
- Helps to keep it DRY (Do not Repeat Yourself)
- Removing tracking logic etc. from the presentational component makes it well testable, which is key.
```javascript
import tracker from './tracker.js';
// HOC
const pageLoadTracking = (ComposedComponent) => class HOC extends Component {
componentDidMount() {
tracker.trackPageLoad(this.props.trackingData);
}
componentDidUpdate() {
tracker.trackPageLoad(this.props.trackingData);
}
render() {
return <ComposedComponent {...this.props} />
}
};
// Usage
import LoginComponent from "./login";
const LoginWithTracking = pageLoadTracking(LoginComponent);
class SampleComponent extends Component {
render() {
const trackingData = {/** Nested Object **/};
return <LoginWithTracking trackingData={trackingData}/>
}
}
```
================================================
FILE: patterns/2.async-nature-of-setState.md
================================================
# Async Nature Of setState()
On the Async nature of setState()
## Gist:
React batches updates and flushes it out once per frame (perf optimization)
However, in some cases React has no control over batching, hence updates are made synchronously
e.g. eventListeners, Ajax, setTimeout and similar Web APIs.
### Main Idea
setState() does not immediately mutate this.state but creates a pending state transition.
Accessing this.state after calling this method can potentially return the existing value.
There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
#### Run the below code and you will make the following observations:
You can see that in every situation (addEventListener, setTimeout or AJAX call) the state before and the state after are different.
And that render was called immediately after triggering the setState method. But why is that?
Well, it turns out React does not understand and thus cannot control code that doesn't live inside the library.
Timeouts or AJAX calls for example, are developer authored code that executes outside of the context of React.
So why does React synchronously update the state in these cases? Well, because it's trying to be as defensive as possible.
Not being in control means it's not able to do any performance optimisations so it's better to update the state on spot and
make sure the code that follows has access to the latest information available.
```javascript
class TestComponent extends React.Component {
constructor(...args) {
super(...args);
this.state = {
dollars: 10
};
this._saveButtonRef = (btn => { this._btnRef = btn });
[
'_onTimeoutHandler',
'_onMouseLeaveHandler',
'_onClickHandler',
'_onAjaxCallback',
].forEach(propToBind => {
this[propToBind] = this[propToBind].bind(this);
});
}
componentDidMount() {
// Add custom event via `addEventListener`
//
// The list of supported React events does include `mouseleave`
// via `onMouseLeave` prop
//
// However, we are not adding the event the `React way` - this will have
// effects on how state mutates
//
// Check the list here - https://reactjs.org/docs/events.html
this._btnRef.addEventListener('mouseleave', this._onMouseLeaveHandler);
// Add JS timeout
//
// Again,outside React `world` - this will also have effects on how state
// mutates
setTimeout(this._onTimeoutHandler, 10000);
// Make AJAX request
fetch('https://api.github.com/users')
.then(this._onAjaxCallback);
}
render() {
console.log('State in render: ' + JSON.stringify(this.state));
return (
<button
ref={this._saveButtonRef}
onClick={this._onClickHandler}>
'Click me'
</button>
);
}
_onClickHandler() {
console.log('State before (_onClickHandler): ' + JSON.stringify(this.state));
this.setState({
dollars: this.state.dollars + 10
});
console.log('State after (_onClickHandler): ' + JSON.stringify(this.state));
}
_onMouseLeaveHandler() {
console.log('State before (mouseleave): ' + JSON.stringify(this.state));
this.setState({
dollars: this.state.dollars + 20
});
console.log('State after (mouseleave): ' + JSON.stringify(this.state));
}
_onTimeoutHandler() {
console.log('State before (timeout): ' + JSON.stringify(this.state));
this.setState({
dollars: this.state.dollars + 30
});
console.log('State after (timeout): ' + JSON.stringify(this.state));
}
_onAjaxCallback(response) {
if (response.status !== 200) {
console.log('Error in AJAX call: ' + response.statusText);
return;
}
console.log('State before (AJAX call): ' + JSON.stringify(this.state));
this.setState({
dollars: this.state.dollars + 40
});
console.log('State after (AJAX call): ' + JSON.stringify(this.state));
}
};
// Render to DOM
ReactDOM.render(
<TestComponent />,
document.getElementById('app')
);
```
### Possible solution?
We're used to calling setState with one parameter only, but actually, the method's signature support two.
The second argument that you can pass in is a callback function that will always be executed after the state has been updated (whether it's inside React's known context or outside of it).
#### An example might be:
```javascript
_onClickHandler: function _onClickHandler() {
console.log('State before (_onClickHandler): ' + JSON.stringify(this.state));
this.setState({
dollars: this.state.dollars + 10
}, () => {
console.log('Here state will always be updated to latest version!');
console.log('State after (_onClickHandler): ' + JSON.stringify(this.state));
});
}
```
#### A note on the async nature of setstate
To be politically correct, setState, as a method, is always synchronous.
It's just a function that calls something behind the scenes - enqueueState or enqueueCallback on updater.
In fact, here's setState taken directly from React source code:
```javascript
ReactComponent.prototype.setState = function(partialState, callback) {
invariant(
typeof partialState === 'object' ||
typeof partialState === 'function' ||
partialState == null,
'setState(...): takes an object of state variables to update or a ' +
'function which returns an object of state variables.'
);
this.updater.enqueueSetState(this, partialState);
if (callback) {
this.updater.enqueueCallback(this, callback, 'setState');
}
};
```
What's actually sync or async are the effects of calling setState in a React application - the reconciliation algorithm, doing the VDOM comparisons and calling render to update the real DOM.
## Related links:
- https://medium.com/@wereHamster/beware-react-setstate-is-asynchronous-ce87ef1a9cf3#.jhdhncws3
- https://www.bennadel.com/blog/2893-setstate-state-mutation-operation-may-be-synchronous-in-reactjs.htm
================================================
FILE: patterns/3.dependency-injection.md
================================================
# Dependency Injection
In React the need of [dependency injection](https://www.youtube.com/watch?v=IKD2-MAkXyQ) is easily visible. Let's consider the following application tree:
```javascript
// Title.jsx
export default function Title(props) {
return <h1>{ props.title }</h1>;
}
```
```javascript
// Header.jsx
import Title from './Title.jsx';
export default function Header() {
return (
<header>
<Title />
</header>
);
}
```
```javascript
// App.jsx
import Header from './Header.jsx';
class App extends React.Component {
constructor(props) {
super(props);
this.state = { title: 'React Dependency Injection' };
}
render() {
return <Header />;
}
}
```
The string "React Dependency Injection" should somehow reach the Title component.
The direct way of doing this is to pass it from App to Header and then Header to pass it to Title.
However, this may work for these three components but what happens if there are multiple properties and deeper nesting.
Lots of components will have to mention properties that they are not interested in.
It is clear that most React components receive their dependencies via props but the question is how these dependencies reach that point.
One way to achieve dependency injection is by using higher-order component to inject data.
```javascript
// inject.jsx
var title = 'React Dependency Injection';
export default function inject(Component) {
return class Injector extends React.Component {
render() {
return (
<Component
{...this.state}
{...this.props}
title={ title }
/>
)
}
};
}
```
```javascript
// Title.jsx
export default function Title(props) {
return <h1>{ props.title }</h1>;
}
```
```javascript
// Header.jsx
import inject from './inject.jsx';
import Title from './Title.jsx';
var EnhancedTitle = inject(Title);
export default function Header() {
return (
<header>
<EnhancedTitle />
</header>
);
}
```
The title is hidden in a middle layer (higher-order component) where we pass it as a prop to the original Title component.
That's all nice but it solves only half of the problem.
Now we don't have to pass the title down the tree but how this data will reach the enhance.jsx helper.
## Using React's context
React has the concept of context. The context is something that every component may have access to.
It's something like an event bus but for data. A single model which we can access from everywhere.
a place where we'll define the context
```javascript
var context = { title: 'React in patterns' };
class App extends React.Component {
getChildContext() {
return context;
}
// ...
}
App.childContextTypes = {
title: PropTypes.string
};
```
A place where we need data
```javascript
class Inject extends React.Component {
render() {
var title = this.context.title;
// ...
}
}
Inject.contextTypes = {
title: PropTypes.string
};
```
### Related links:
- [What is Dependency Injection?](https://www.youtube.com/watch?v=IKD2-MAkXyQ)
- [The Basics of Dependency Injection](https://www.youtube.com/watch?v=jXhdOTw1q5Q)
- [Dependency injection in JavaScript](http://krasimirtsonev.com/blog/article/Dependency-injection-in-JavaScript)
- [DI In React](https://github.com/krasimir/react-in-patterns/blob/master/book/chapter-10/README.md)
================================================
FILE: patterns/4.context-wrapper.md
================================================
# Context Wrapper
It is a good practice that our context is not just a plain object but it has an interface that allows us to store and retrieve data. For example:
```javascript
// dependencies.js
export default {
data: {},
get(key) {
return this.data[key];
},
register(key, value) {
this.data[key] = value;
}
}
```
Then, if we go back to our example, the very top App component may look like that:
```javascript
import dependencies from './dependencies';
dependencies.register('title', 'React in patterns');
class App extends React.Component {
getChildContext() {
return dependencies;
}
render() {
return <Header />;
}
}
App.childContextTypes = {
data: PropTypes.object,
get: PropTypes.func,
register: PropTypes.func
};
```
And our Title component gets it's data through the context:
```javascript
// Title.jsx
export default class Title extends React.Component {
render() {
return <h1>{ this.context.get('title') }</h1>
}
}
Title.contextTypes = {
data: PropTypes.object,
get: PropTypes.func,
register: PropTypes.func
};
```
Ideally we don't want to specify the contextTypes every time when we need an access to the context.
This detail may be wrapped in a higher-order component.
And even more, we may write an utility function that is more descriptive and helps us declare the exact wiring.
ie. instead of accessing the context directly with this.context.get('title') we ask the higher-order component to
get what we need and to pass it as a prop to our component.
For example:
```javascript
// Title.jsx
import wire from './wire';
function Title(props) {
return <h1>{ props.title }</h1>;
}
export default wire(Title, ['title'], function resolve(title) {
return { title };
});
```
The wire function accepts first a React component, then an array with all the needed dependencies
(which are registered already) and then a function which I like to call mapper.
It receives what's stored in the context as a raw data and returns an object which is the actual
React props for our component (Title). In this example we just pass what we get - a title string variable.
However, in a real app this could be a collection of data stores, configuration or something else.
So, it's nice that we pass exactly what we need and don't pollute the components with data that they don't need.
Here is how the wire function looks like:
```javascript
export default function wire(Component, dependencies, mapper) {
class Inject extends React.Component {
render() {
var resolved = dependencies.map(this.context.get.bind(this.context));
var props = mapper(...resolved);
return React.createElement(Component, props);
}
}
Inject.contextTypes = {
data: PropTypes.object,
get: PropTypes.func,
register: PropTypes.func
};
return Inject;
};
```
Inject is a higher-order component that gets access to the context and retrieves all the items listed under dependencies array.
The mapper is a function receiving the context data and transforms it to props for our component.
#### Non-context alternative
Use a singleton to register/fetch all dependencies
```javascript
var dependencies = {};
export function register(key, dependency) {
dependencies[key] = dependency;
}
export function fetch(key) {
if (key in dependencies) return dependencies[key];
throw new Error(`"${ key } is not registered as dependency.`);
}
export function wire(Component, deps, mapper) {
return class Injector extends React.Component {
constructor(props) {
super(props);
this._resolvedDependencies = mapper(...deps.map(fetch));
}
render() {
return (
<Component
{...this.state}
{...this.props}
{...this._resolvedDependencies}
/>
);
}
};
}
```
We'll store the dependencies in dependencies global variable (it's global for our module, not at an application level).
We then export two functions register and fetch that write and read entries.
It looks a little bit like implementing setter and getter against a simple JavaScript object.
Then we have the wire function that accepts our React component and returns a higher-order component.
In the constructor of that component we are resolving the dependencies and later while rendering the original component we pass them as props.
We follow the same pattern where we describe what we need (deps argument) and extract the needed props with a mapper function.
Having the di.jsx helper we are again able to register our dependencies at the entry point of our application (app.jsx) and inject them wherever (Title.jsx) we need.
```javascript
// app.jsx
import Header from './Header.jsx';
import { register } from './di.jsx';
register('my-awesome-title', 'React in patterns');
class App extends React.Component {
render() {
return <Header />;
}
}
```
```javascript
// Header.jsx
import Title from './Title.jsx';
export default function Header() {
return (
<header>
<Title />
</header>
);
}
```
```javascript
// Title.jsx
import { wire } from './di.jsx';
var Title = function(props) {
return <h1>{ props.title }</h1>;
};
export default wire(Title, ['my-awesome-title'], title => ({ title }));
```
If we look at the `Title.jsx` file we'll see that the actual component and the wiring may live in different files.
That way the component and the mapper function become easily unit testable.
================================================
FILE: patterns/5.event-handlers.md
================================================
# Event Handlers
Binding event handlers in the constructor.
Most of the times we handle DOM events in the component that contains the elements dispatching the events.
Like in the example below, we have a click handler and we want to run a function or method of the same component:
```javascript
class Switcher extends React.Component {
render() {
return (
<button onClick={ this._handleButtonClick }>
click me
</button>
);
}
_handleButtonClick() {
console.log('Button is clicked');
}
}
```
That's all fine because `_handleButtonClick` is a function and we indeed pass a function to the onClick attribute.
The problem is that as it is the code doesn't keep the scope. So, if we have to use `this` inside `_handleButtonClick` we'll get an error.
```javascript
class Switcher extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'React in patterns' };
}
render() {
return (
<button onClick={ this._handleButtonClick }>
click me
</button>
);
}
_handleButtonClick() {
console.log(`Button is clicked inside ${ this.state.name }`);
// leads to
// Uncaught TypeError: Cannot read property 'state' of null
}
}
```
What we normally do is to use bind like so:
```javascript
<button onClick={ this._handleButtonClick.bind(this) }>
click me
</button>
```
However, this means that the bind function is called again and again because we may render the button many times.
A better approach would be to create the bindings in the constructor of the component:
```javascript
class Switcher extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'React in patterns' };
this._buttonClick = this._handleButtonClick.bind(this);
}
render() {
return (
<button onClick={ this._buttonClick }>
click me
</button>
);
}
_handleButtonClick() {
console.log(`Button is clicked inside ${ this.state.name }`);
}
}
```
The other alternative is to use arrow functions for the onClick prop function assignment.
Arrow functions don't affect the context at invocation time (`this` value from the surrounding scope is used).
Facebook by the way recommend the same technique while dealing with functions that need the context of the same component.
The binding in the constructor may be also useful if we pass callbacks down the tree.
A short hand example using arrow functions and avoid having to use the constructor:
```javascript
class Switcher extends React.Component {
state = { name: 'React in patterns' };
render() {
return (
<button onClick={ this._handleButtonClick }>
click me
</button>
);
}
_handleButtonClick = () => {
console.log(`Button is clicked inside ${ this.state.name }`);
}
}
```
================================================
FILE: patterns/6.flux-pattern.md
================================================
# Flux pattern for data handling
**Simple dispatcher**
```javascript
var Dispatcher = function () {
return {
_stores: [],
register: function (store) {
this._stores.push({store: store});
},
dispatch: function (action) {
if (this._stores.length > 0) {
this._stores.forEach(function (entry) {
entry.store.update(action);
});
}
}
}
};
```
We expect the store to have an update method(), so let's modify register to expect it.
```javascript
function register(store) {
if (!store || !store.update || typeof store.update !== 'function') {
throw new Error('You should provide a store that has an update method');
} else {
this._stores.push({store: store});
}
}
```
**Full blown Dispatcher**
```javascript
var Dispatcher = function () {
return {
_stores: [],
register: function (store) {
if (!store || !store.update) {
throw new Error('You should provide a store that has an `update` method.');
} else {
var consumers = [];
var change = function () {
consumers.forEach(function (l) {
l(store);
});
};
var subscribe = function (consumer, noInit) {
consumers.push(consumer);
!noInit ? consumer(store) : null;
};
this._stores.push({store: store, change: change});
return subscribe;
}
},
dispatch: function (action) {
if (this._stores.length > 0) {
this._stores.forEach(function (entry) {
entry.store.update(action, entry.change);
});
}
}
}
};
module.exports = {
create: function () {
var dispatcher = Dispatcher();
return {
createAction: function (type) {
if (!type) {
throw new Error('Please, provide action\'s type.');
} else {
return function (payload) {
return dispatcher.dispatch({type: type, payload: payload});
}
}
},
createSubscriber: function (store) {
return dispatcher.register(store);
}
}
}
};
```
### Related links:
- https://github.com/krasimir/react-in-patterns/tree/master/patterns/flux
================================================
FILE: patterns/7.one-way-data-flow.md
================================================
# One way data flow
One-way direction data flow eliminates multiple states and deals with only one which is usually inside the store.
To achieve that our Store object needs logic that allows us to subscribe for changes:
```javascript
var Store = {
_handlers: [],
_flag: '',
onChange: function (handler) {
this._handlers.push(handler);
},
set: function (value) {
this._flag = value;
this._handlers.forEach(handler => handler())
},
get: function () {
return this._flag;
}
};
```
Then we will hook our main App component and we'll re-render it every time when the Store changes its value:
```javascript
class App extends React.Component {
constructor(props) {
super(props);
Store.onChange(this.forceUpdate.bind(this));
}
render() {
return (
<div>
<Switcher
value={ Store.get() }
onChange={ Store.set.bind(Store) }/>
</div>
);
}
}
```
Notice that we are using forceUpdate which is not really recommended.
Normally a high-order component is used to enable the re-rendering. We used forceUpdate just to keep the example simple.
Because of this change the Switcher becomes really simple. We don't need the internal state:
```javascript
class Switcher extends React.Component {
constructor(props) {
super(props);
this._onButtonClick = e => {
this.props.onChange(!this.props.value);
}
}
render() {
return (
<button onClick={ this._onButtonClick }>
{ this.props.value ? 'lights on' : 'lights off' }
</button>
);
}
}
```
The benefit that comes with this pattern is that our components become dummy representation of the Store's data.
It's really easy to think about the React components as views (renderers).
We write our application in a declarative way and deal with the complexity in only one place.
### Related links:
- https://www.startuprocket.com/articles/evolution-toward-one-way-data-flow-a-quick-introduction-to-redux
================================================
FILE: patterns/8.presentational-vs-container.md
================================================
# Presentational and Container components
#### Problem
Data and logic together.
```javascript
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {time: this.props.time};
this._update = this._updateTime.bind(this);
}
render() {
var time = this._formatTime(this.state.time);
return (
<h1>{ time.hours } : { time.minutes } : { time.seconds }</h1>
);
}
componentDidMount() {
this._interval = setInterval(this._update, 1000);
}
componentWillUnmount() {
clearInterval(this._interval);
}
_formatTime(time) {
var [ hours, minutes, seconds ] = [
time.getHours(),
time.getMinutes(),
time.getSeconds()
].map(num => num < 10 ? '0' + num : num);
return {hours, minutes, seconds};
}
_updateTime() {
this.setState({time: new Date(this.state.time.getTime() + 1000)});
}
}
ReactDOM.render(<Clock time={ new Date() }/>, ...);
```
#### Solution
Let's split the component into two parts - container and presentation.
#### Container Component
Containers know about data, it's shape and where it comes from. They know details about how the things work or the so called business logic.
They receive information and format it so it is easy to use by the presentational component. Very often we use higher-order components to create containers.
Their render method contains only the presentational component.
```javascript
// Clock/index.js
import Clock from './Clock.jsx'; // <-- that's the presentational component
export default class ClockContainer extends React.Component {
constructor(props) {
super(props);
this.state = {time: props.time};
this._update = this._updateTime.bind(this);
}
render() {
return <Clock { ...this._extract(this.state.time) }/>;
}
componentDidMount() {
this._interval = setInterval(this._update, 1000);
}
componentWillUnmount() {
clearInterval(this._interval);
}
_extract(time) {
return {
hours: time.getHours(),
minutes: time.getMinutes(),
seconds: time.getSeconds()
};
}
_updateTime() {
this.setState({time: new Date(this.state.time.getTime() + 1000)});
}
};
```
#### Presentational component
Presentational components are concerned with how the things look. They have the additional markup needed for making the page pretty.
Such components are not bound to anything and have no dependencies.
Very often implemented as a stateless functional components they don't have internal state.
```javascript
// Clock/Clock.jsx
export default function Clock(props) {
var [ hours, minutes, seconds ] = [
props.hours,
props.minutes,
props.seconds
].map(num => num < 10 ? '0' + num : num);
return <h1>{ hours } : { minutes } : { seconds }</h1>;
};
```
The nice things about containers is that they encapsulate logic and may inject data into different renderers.
Very often a file that exports a container is not sending out a class directly but a function.
For example, instead of using
```javascript
import Clock from './Clock.jsx';
export default class ClockContainer extends React.Component {
render() {
return <Clock />;
}
}
```
We may export a function that accepts the presentational component:
```javascript
export default function (Component) {
return class Container extends React.Component {
render() {
return <Component />;
}
}
}
```
Using this technique our container is really flexible in rendering its result.
It will be really helpful if we want to switch from digital to analog clock representation.
### Related links:
- https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.mbglcakmp
- https://github.com/krasimir/react-in-patterns/tree/master/patterns/presentational-and-container
- https://medium.com/@learnreact/container-components-c0e67432e005
================================================
FILE: patterns/9.third-party-integration.md
================================================
# Third Party Integration
Mixing 3rd party integrations/libraries with React
In this example we'll see how to mix React and jQuery's UI plugin.
We pick tag-it jQuery plugin for the example. It transforms an unordered list to input field for managing tags:
```html
<ul>
<li>JavaScript</li>
<li>CSS</li>
</ul>
```
To make it work we have to include jQuery, jQuery UI and the tag-it plugin code. It works like that:
```javascript
$('<dom element selector>').tagit();
```
We select a DOM element and call tagit().
The very first thing that we have to do is to force a single-render of the Tags component.
That's because when React adds the elements in the actual DOM we want to pass the control of them to jQuery.
If we skip this both React and jQuery will work on same DOM elements without knowing for each other. To achieve a single-render we have to use the lifecycle method `shouldComponentUpdate`
Let's say that we want to programmatically add a new tag to the already running tag-it field.
Such action will be triggered by the React component and needs to use the jQuery API.
We have to find a way to communicate data to Tags component but still keep the single-render approach.
To illustrate the whole process we will add an input field to the App class and a button which if clicked will pass a string to Tags component.
```javascript
class App extends React.Component {
constructor(props) {
super(props);
this._addNewTag = this._addNewTag.bind(this);
this.state = {
tags: ['JavaScript', 'CSS'],
newTag: null
};
}
_addNewTag() {
this.setState({newTag: this.refs.field.value});
}
render() {
return (
<div>
<p>Add new tag:</p>
<div>
<input type='text' ref='field'/>
<button onClick={ this._addNewTag }>Add</button>
</div>
<Tags tags={ this.state.tags } newTag={ this.state.newTag }/>
</div>
);
}
}
```
We use the internal state as a data storage for the value of the newly added field.
Every time when we click the button we update the state and trigger re-rendering of Tags component.
However, because of shouldComponentUpdate we update nothing.
The only one change is that we get a value of the newTag prop which may be captured via another lifecycle method - componentWillReceiveProps
```javascript
class Tags extends React.Component {
componentDidMount() {
this.list = $(this.refs.list);
this.list.tagit();
}
shouldComponentUpdate() {
return false;
}
componentWillReceiveProps(newProps) {
this.list.tagit('createTag', newProps.newTag);
}
render() {
return (
<ul ref='list'>
{ this.props.tags.map((tag, i) => <li key={ i }>{ tag } </li>) }
</ul>
);
}
}
```
### Related links:
- https://github.com/krasimir/react-in-patterns/tree/master/patterns/third-party
================================================
FILE: perf-tips/01.shouldComponentUpdate-check.md
================================================
# shouldComponentUpdate() check
`shouldComponentUpdate` check to avoid expensive re-renders
React Components re-render every time their props or state change.
So imagine having to render the entire page every time there in an action. That takes a big load on the browser.
That’s where ShouldComponentUpdate comes in, whenever React is rendering the view it checks to see
if shouldComponentUpdate is returning false/true. So whenever you have a component that’s static do yourself a favor and return false.
Or if is not static check to see if the props/state has changed.
#### Bad
```javascript
const AutocompleteItem = (props) => {
const selectedClass = props.selected === true ? "selected" : "";
var path = parseUri(props.url).path;
path = path.length <= 0 ? props.url : "..." + path;
return (
<li
onMouseLeave={props.onMouseLeave}
className={selectedClass}>
<i className="ion-ios-eye"
data-image={props.image}
data-url={props.url}
data-title={props.title}
onClick={props.handlePlanetViewClick}/>
<span
onMouseEnter={props.onMouseEnter}
>
<div className="dot bg-mint"/>
{path}
</span>
</li>
);
};
```
#### Good
```javascript
export default class AutocompleteItem extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.url !== this.props.url ||
nextProps.selected !== this.props.selected;
}
render() {
const {props} = this;
const selectedClass = props.selected === true ? "selected" : "";
var path = parseUri(props.url).path;
path = path.length <= 0 ? props.url : "..." + path;
return (
<li
onMouseLeave={props.onMouseLeave}
className={selectedClass}>
<i className="ion-ios-eye"
data-image={props.image}
data-url={props.url}
data-title={props.title}
onClick={props.handlePlanetViewClick}/>
<span
onMouseEnter={props.onMouseEnter}>
<div className="dot bg-mint"/>
{path}
</span>
</li>
);
}
}
```
### Related links:
- [React Performance optimization](https://medium.com/@nesbtesh/react-performance-optimization-28ec5b61fff3)
- [React rendering misconception](https://robots.thoughtbot.com/react-rendering-misconception)
================================================
FILE: perf-tips/02.pure-component.md
================================================
# Using Pure Components
Pure Components do shallow equality checks in `shouldComponentUpdate` by default. This is intended to prevent renders when neither props nor state have changed.
Recompose offers a Higher Order Component called `pure` for this purpose and React added `React.PureComponent` in v15.3.0.
#### Bad
```javascript
export default (props, context) => {
// ... do expensive compute on props ...
return <SomeComponent {...props} />
}
```
#### Good
```javascript
import { pure } from 'recompose';
// This won't be called when the props DONT change
export default pure((props, context) => {
// ... do expensive compute on props ...
return <SomeComponent someProp={props.someProp}/>
})
```
#### Better
```javascript
// This is better mainly because it uses no external dependencies.
import { PureComponent } from 'react';
export default class Example extends PureComponent {
// This won't re-render when the props DONT change
render() {
// ... do expensive compute on props ...
return <SomeComponent someProp={props.someProp}/>
}
}
})
```
### Related links:
- [Recompose](https://github.com/acdlite/recompose#composition)
- [Higher Order Components with Functional Patterns Using Recompose](https://egghead.io/courses/higher-order-components-with-functional-patterns-using-recompose)
- [React: PureComponent](https://reactjs.org/docs/react-api.html#reactpurecomponent)
- [Pure Components](https://www.fullstackreact.com/30-days-of-react/day-11/)
- [Top 5 Recompose HOCs](https://medium.com/@abhiaiyer/top-5-recompose-hocs-1a4c9cc4566)
================================================
FILE: perf-tips/03.reselect.md
================================================
# Using reselect
Use Reselect in Redux connect(mapState) -- to avoid frequent re-render.
#### Bad
```javascript
let App = ({otherData, resolution}) => (
<div>
<DataContainer data={otherData}/>
<ResolutionContainer resolution={resolution}/>
</div>
);
const doubleRes = (size) => ({
width: size.width * 2,
height: size.height * 2
});
App = connect(state => {
return {
otherData: state.otherData,
resolution: doubleRes(state.resolution)
}
})(App);
```
In this above case every time otherData in the state changes both DataContainer and ResolutionContainer
will be rendered even when the resolution in the state does not change.
This is because the doubleRes function will always return a new resolution object with a new identity.
If doubleRes is written with Reselect the issue goes away:
Reselect memoizes the last result of the function and returns it when called until new arguments are passed to it.
#### Good
```javascript
import { createSelector } from 'reselect';
const doubleRes = createSelector(
r => r.width,
r => r.height,
(width, height) => ({
width: width * 2,
height: height * 2
})
);
```
### Related links:
- [React](https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#.cz2ypc2ob)
- [Computing Derived Data: Docs](http://redux.js.org/docs/recipes/ComputingDerivedData.html)
================================================
FILE: perf-tips/README.md
================================================
# Perf Tips
**Key Ideas**
- Avoid Reconciliation with shouldComponentUpdate() check
- Use Immutable Data Structures
- Use Production Build
- Profile Components with Chrome Timeline
- Defer computationally expensive tasks in componentWillMount/componentDidMount by using setTimeout and/or requestAnimationFrame
## Articles
[Optimizing Performance: Docs](https://reactjs.org/docs/optimizing-performance.html)
[Performance Engineering with React](http://benchling.engineering/performance-engineering-with-react/)
[Tips to optimise rendering of a set of elements in React](https://blog.lavrton.com/how-to-optimise-rendering-of-a-set-of-elements-in-react-ad01f5b161ae)
[React.js Best Practices for 2016](https://blog.risingstack.com/react-js-best-practices-for-2016/)
================================================
FILE: styling/01.stateless-ui-components.md
================================================
# Styling in stateless UI components
Keep styles separated from the parts of the app that are tied to state.
That means routes, views, containers, forms, layouts, etc. should not have any styling or classes in them.
Instead, these heavy-lifting components should be composed of primarily stateless functional UI components.
Form component (with no styles/classNames) - just pure composed components
```javascript
class SampleComponent extends Component {
render() {
return (
<form onSubmit={this.handleSubmit}>
<Heading children='Sign In'/>
<Input
name='username'
value={username}
onChange={this.handleChange}/>
<Input
type='password'
name='password'
value={password}
onChange={this.handleChange}/>
<Button
type='submit'
children='Sign In'/>
</form>
)
}
}
// Presentational component (with Styles)
const Button = ({
...props
}) => {
const sx = {
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: 'bold',
textDecoration: 'none',
display: 'inline-block',
margin: 0,
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 16,
paddingRight: 16,
border: 0,
color: 'white',
backgroundColor: 'blue',
WebkitAppearance: 'none',
MozAppearance: 'none'
}
return (
<button {...props} style={sx}/>
)
}
```
================================================
FILE: styling/02.styles-module.md
================================================
# Styles module
Generally, hard coding styles values in a component should be avoided.
Any values that are likely to be used across different UI components should be split into their own module.
```javascript
// Styles module
export const white = '#fff';
export const black = '#111';
export const blue = '#07c';
export const colors = {
white,
black,
blue
};
export const space = [
0,
8,
16,
32,
64
];
const styles = {
bold: 600,
space,
colors
};
export default styles
```
#### Usage
```javascript
// button.jsx
import React from 'react'
import { bold, space, colors } from './styles'
const Button = ({
...props
}) => {
const sx = {
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: bold,
textDecoration: 'none',
display: 'inline-block',
margin: 0,
paddingTop: space[1],
paddingBottom: space[1],
paddingLeft: space[2],
paddingRight: space[2],
border: 0,
color: colors.white,
backgroundColor: colors.blue,
WebkitAppearance: 'none',
MozAppearance: 'none'
};
return (
<button {...props} style={sx}/>
)
};
```
================================================
FILE: styling/03.style-functions.md
================================================
# Style Functions
Since we’re using JavaScript, we can also employ helper functions for styling elements.
#### Example 1
A function to create rgba values of black
```javascript
const darken = (n) => `rgba(0, 0, 0, ${n})`;
darken(1 / 8); // 'rgba(0, 0, 0, 0.125)'
const shade = [
darken(0),
darken(1 / 8),
darken(1 / 4),
darken(3 / 8),
darken(1 / 2),
darken(5 / 8),
darken(3 / 4),
darken(7 / 8),
darken(1)
];
// So now,
// shade[4] is 'rgba(0, 0, 0, 0.5)'
```
#### Example 2
Creating a scale for margin and padding to help keep visual rhythm consistent
```javascript
// Modular powers of two scale
const scale = [
0,
8,
16,
32,
64
];
// Functions to get partial style objects
const createScaledPropertyGetter = (scale) => (prop) => (x) => {
return (typeof x === 'number' && typeof scale[x] === 'number')
? {[prop]: scale[x]}
: null
};
const getScaledProperty = createScaledPropertyGetter(scale);
export const getMargin = getScaledProperty('margin');
export const getPadding = getScaledProperty('padding');
// Style function usage
const Box = ({
m,
p,
...props
}) => {
const sx = {
...getMargin(m),
...getPadding(p)
};
return <div {...props} style={sx}/>
};
// Component usage
const Box = () => (
<div>
<Box m={2} p={3}>
A box with 16px margin and 32px padding
</Box>
</div>
);
```
================================================
FILE: styling/04.using-npm-modules.md
================================================
# Using npm modules
For more complex color/style transformation logic, it's always good to use it from a separate npm module (or) create one.
#### Example
For darkening scales in CSS you can use `chroma-js` module
```javascript
import chroma from 'chroma-js'
const alpha = (color) => (a) => chroma(color).alpha(a).css();
const darken = alpha('#000');
const shade = [
darken(0),
darken(1 / 8),
darken(1 / 4)
// More...
];
const blueAlpha = [
alpha(blue)(0),
alpha(blue)(1 / 4),
alpha(blue)(1 / 2),
alpha(blue)(3 / 4),
alpha(blue)(1)
];
```
================================================
FILE: styling/05.base-component.md
================================================
# Base Component
### Using a Base Component
There is tremendous amount of flexibility when it comes to composition in React – since components are essentially just functions.
By changing style details in a component to props we can make it more reusable.
The color and backgroundColor properties have been moved up to the component’s props.
Additionally, we’ve added a big prop to adjust the padding top and bottom.
```javascript
const Button = ({
big,
color = colors.white,
backgroundColor = colors.blue,
...props
}) => {
const sx = {
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: bold,
textDecoration: 'none',
display: 'inline-block',
margin: 0,
paddingTop: big ? space[2] : space[1],
paddingBottom: big ? space[2] : space[1],
paddingLeft: space[2],
paddingRight: space[2],
border: 0,
color,
backgroundColor,
WebkitAppearance: 'none',
MozAppearance: 'none'
};
return (
<button {...props} style={sx}/>
)
};
```
#### Usage
```javascript
const Button = () => (
<div>
<Button>
Blue Button
</Button>
<Button big backgroundColor={colors.red}>
Big Red Button
</Button>
</div>
);
// By adjusting the props API of the base Button component,
// an entire set of button styles can be created.
const ButtonBig = (props) => <Button {...props} big/>;
const ButtonGreen = (props) => <Button {...props} backgroundColor={colors.green}/>;
const ButtonRed = (props) => <Button {...props} backgroundColor={colors.red}/>;
const ButtonOutline = (props) => <Button {...props} outline/>;
```
================================================
FILE: styling/06.layout-component.md
================================================
# Layout component
We can extend the idea of [Base components](./05.base-component.md) to create Layout components.
#### Example
```javascript
const Grid = (props) => (
<Box {...props}
display='inline-block'
verticalAlign='top'
px={2}/>
);
const Half = (props) => (
<Grid {...props}
width={1 / 2}/>
);
const Third = (props) => (
<Grid {...props}
width={1 / 3}/>
);
const Quarter = (props) => (
<Grid {...props}
width={1 / 4}/>
);
const Flex = (props) => (
<Box {...props}
display='flex'/>
);
const FlexAuto = (props) => (
<Box {...props}
flex='1 1 auto'/>
);
```
#### Usage
```javascript
const Layout = () => (
<div>
<div>
<Half>Half width column</Half>
<Half>Half width column</Half>
</div>
<div>
<Third>Third width column</Third>
<Third>Third width column</Third>
<Third>Third width column</Third>
</div>
<div>
<Quarter>Quarter width column</Quarter>
<Quarter>Quarter width column</Quarter>
<Quarter>Quarter width column</Quarter>
<Quarter>Quarter width column</Quarter>
</div>
</div>
);
```
### Related links:
- [Github: React Layout components](https://github.com/rofrischmann/react-layout-components)
- [Leveling Up With React: Container Components](https://css-tricks.com/learning-react-container-components/)
- [Container Components and Stateless Functional Components in React](Leveling Up With React: Container Components)
================================================
FILE: styling/07.typography-component.md
================================================
# Typography Component
We can extend the idea of [Base components](./05.base-component.md) to create Typography components
this pattern helps ensure consistency and keep your styling DRY.
#### Example
```javascript
import React from 'react';
import { alternateFont, typeScale, boldFontWeight } from './styles';
const Text = ({
tag = 'span',
size = 4,
alt,
center,
bold,
caps,
...props
}) => {
const Tag = tag;
const sx = {
fontFamily: alt ? alternateFont : null,
fontSize: typeScale[size],
fontWeight: bold ? boldFontWeight : null,
textAlign: center ? 'center' : null,
textTransform: caps ? 'uppercase' : null
};
return <Tag {...props} style={sx}/>
};
const LeadText = (props) => <Text {...props} tag='p' size={3}/>;
const Caps = (props) => <Text {...props} caps/>;
const MetaText = (props) => <Text {...props} size={5} caps/>;
const AltParagraph = (props) => <Text {...props} tag='p' alt/>;
const CapsButton = ({ children, ...props }) => (
<Button {...props}>
<Caps>
{children}
</Caps>
</Button>
);
```
#### Usage
```javascript
const TypographyComponent = () => (
<div>
<LeadText>
This is a lead with some<Caps>all caps</Caps>.
It has a larger font size than the default paragraph.
</LeadText>
<MetaText>
This is smaller text, like form helper copy.
</MetaText>
</div>
);
```
================================================
FILE: styling/08.HOC-for-styling.md
================================================
# Using HOC for styling
Sometimes there are isolated UI components that only require a minimal amount of state for interaction, and using them as standalone components is sufficient
eg. Interactions in a Carousel
#### Example: Carousel
The HOC will have a current slide index and have previous and next methods.
```javascript
// Higher order component
import React from 'react'
// This could be named something more generic like Counter or Cycle
const CarouselContainer = (Comp) => {
class Carousel extends React.Component {
constructor() {
super();
this.state = {
index: 0
};
this.previous = () => {
const { index } = this.state;
if (index > 0) {
this.setState({index: index - 1})
}
};
this.next = () => {
const { index } = this.state;
this.setState({index: index + 1})
}
}
render() {
return (
<Comp
{...this.props}
{...this.state}
previous={this.previous}
next={this.next}/>
)
}
}
return Carousel
};
export default CarouselContainer;
```
#### Using the HOC
```javascript
// UI component
const Carousel = ({ index, ...props }) => {
const length = props.length || props.children.length || 0;
const sx = {
root: {
overflow: 'hidden'
},
inner: {
whiteSpace: 'nowrap',
height: '100%',
transition: 'transform .2s ease-out',
transform: `translateX(${index % length * -100}%)`
},
child: {
display: 'inline-block',
verticalAlign: 'middle',
whiteSpace: 'normal',
outline: '1px solid red',
width: '100%',
height: '100%'
}
};
const children = React.Children.map(props.children, (child, i) => {
return (
<div style={sx.child}>
{child}
</div>
)
});
return (
<div style={sx.root}>
<div style={sx.inner}>
{children}
</div>
</div>
)
};
// Final Carousel component
const HeroCarousel = (props) => {
return (
<div>
<Carousel index={props.index}>
<div>Slide one</div>
<div>Slide two</div>
<div>Slide three</div>
</Carousel>
<Button
onClick={props.previous}
children='Previous'/>
<Button
onClick={props.next}
children='Next'/>
</div>
)
};
// Wrap the component with the functionality from the higher order component
export default CarouselContainer(HeroCarousel)
```
By keeping the styling separate from the interactive state, any number of carousel variations can be created from these reusable parts.
#### Usage
```javascript
const Carousel = () => (
<div>
<HeroCarousel />
</div>
);
```
================================================
FILE: styling/README.md
================================================
# Styling in React
Here we look into some ideas around using CSS in JS.
If you are pondering over why to use CSS in JS, I highly recommend this [talk](http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html) by [Vjeux](https://twitter.com/Vjeux)
## Articles
[Patterns for style composition in React](https://jxnblk.com/blog/patterns-for-style-composition-in-react/)
[Inline style vs stylesheet performance](https://www.ctheu.com/2015/08/17/react-inline-styles-vs-css-stupid-benchmark/)
================================================
FILE: ux-variations/01.composing-variations.md
================================================
# Using Composition to handle UX variations
Combining smaller reusable components to build a bigger UI blocks.
**How do we make sure components are reusable?**
- By ensuring our UI components are pure presentational components (dumb)
**What does reusable mean?**
- No data fetching within the component (do it in Redux).
- If data is required from API - goes into Redux
Via redux-thunk API calls are isolated away from the redux containers that deal with the data obtained and pass it on to the dumb component.
If we have a bunch of renderBla() functions within the component which are used in the main component render()
- It’s better to move it to separate components. That way it is reusable.
### Example
Login page variations
UX variations toggle features + add in additional links/markup.
If the UX variations are involved toggling features within a component + adding minor markup around it
```javascript
import React, { Component } from "react";
import PropTypes from 'prop-types';
import SignIn from "./sign-in";
class MemberSignIn extends Component {
_renderMemberJoinLinks() {
return (
<div className="member-signup-links">
...
</div>
);
}
_routeTo() {
// Routing logic here
}
render() {
const {forgotEmailRoute,forgotPwdRoute, showMemberSignupLinks} = this.props;
return (
<div>
<SignIn
onForgotPasswordRequested={this._routeTo(forgotPwdRoute)}
onForgotEmailRequested={this._routeTo(forgotEmailRoute)}>
{this.props.children}
{showMemberSignupLinks && this._renderMemberJoinLinks()}
</SignIn>
</div>
);
}
}
export default MemberSignIn;
```
### Related links:
- [Slides from my talk: Building Multi-tenant UI with React](https://speakerdeck.com/vasa/building-multitenant-ui-with-react-dot-js)
================================================
FILE: ux-variations/02.toggle-ui-elements.md
================================================
# Toggle UI Elements
Handling minor UX variations in the component by toggling ON/OFF features.
Modify the component to take in a prop to control it’s behavior.
### Gotcha:
Easy to overuse this idea by adding props for every variation.
- Only add in props for features specific to the current feature that the component.
- Basically, not violate the Single Responsibility Principle.
#### Example
Show/Hide password feature in Login form
```javascript
class PasswordField extends Component {
render() {
const {
password,
showHidePassword,
showErrorOnTop,
showLabels,
shouldComplyAda
} = this.props;
return (
<div>
<Password
field={password}
label="Password"
showErrorOnTop={showErrorOnTop}
placeholder={shouldComplyAda ? "" : "Password"}
showLabel={showLabels}
showHidePassword={showHidePassword}
/>
</div>
);
}
}
```
### Related links:
- [Slides from my talk: Building Multi-tenant UI with React](https://speakerdeck.com/vasa/building-multitenant-ui-with-react-dot-js)
================================================
FILE: ux-variations/03.HOC-feature-toggles.md
================================================
# HOC for Feature Toggles
Using Higher order components (HOC) for UX variations
eg. Toggling features On/Off
```javascript
// featureToggle.js
const isFeatureOn = function (featureName) {
// return true or false
};
import { isFeatureOn } from './featureToggle';
const toggleOn = (featureName, ComposedComponent) => class HOC extends Component {
render() {
return isFeatureOn(featureName) ? <ComposedComponent {...this.props} /> : null;
}
};
// Usage
import AdsComponent from './Ads'
const Ads = toggleOn('ads', AdsComponent);
```
================================================
FILE: ux-variations/04.HOC-props-proxy.md
================================================
# Higher Order Component - Props proxy
This basically helps to add/edit props passed to the Component.
```javascript
function HOC(WrappedComponent) {
return class Test extends Component {
render() {
const newProps = {
title: 'New Header',
footer: false,
showFeatureX: false,
showFeatureY: true
};
return <WrappedComponent {...this.props} {...newProps} />
}
}
}
```
================================================
FILE: ux-variations/05.wrapper-components.md
================================================
# Wrapper Components
Using Wrappers to handle UX/style variations
For Handling Wrapper ``<div>``’s and other markup around component, use composition!
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags.
Parent can read its children by accessing the special this.props.children prop.
```javascript
const SampleComponent = () => {
<Parent>
<Child />
</Parent>
};
const Parent = () => {
// You can use class 'bla' or any other classes to handle any style variations for the same markup.
<div className="bla">
{this.props.children}
</div>
};
```
FYI - Wrapper component can also be made accept a tag name and then used to generate the HTML element.
However, usually this is not recommended because you can't add attributes/props to it.
```javascript
const SampleComponent = () => {
<Wrap tagName="div" content="Hello World" />
};
const Wrap = ({ tagName, content }) => {
const Tag = `${tagName}` // variable name must begin with capital letters
return <Tag>{content}</Tag>
}
```
### Related links:
- [Slides from my talk: Building Multi-tenant UI with React](https://speakerdeck.com/vasa/building-multitenant-ui-with-react-dot-js)
================================================
FILE: ux-variations/06.display-order-variations.md
================================================
# Display UI elements in different order
Use a prop to specify order – Map through ReactElements and render it based on order prop.
```javascript
class PageSections extends Component {
render() {
const pageItems = this.props.contentOrder.map(
(content) => {
const renderFunc = this.contentOrderMap[content];
return (typeof renderFunc === 'function') ? renderFunc() : null;
}
);
return (
<div className="page-content">
{pageItems}
</div>
)
}
}
```
### Related links:
- [Slides from my talk: Building Multi-tenant UI with React](https://speakerdeck.com/vasa/building-multitenant-ui-with-react-dot-js)
================================================
FILE: ux-variations/README.md
================================================
# Handling UX variations for multiple brands and apps
## [Slides from my talk](https://speakerdeck.com/vasa/building-multitenant-ui-with-react-dot-js)
A few general coding principles which help write reusable React components
## Single Responsibility Principle
**In React**
Components/Containers code must essentially deal with only one chunk of the UI feature/functionality.
* Eg. Shipping Address component
* Address container (Only has address related fields), Name container (first and last name), Phone component, State, City and Zip code container
**In Redux**
All API related call go into Redux thunks/other async handling sections (redux-promise, sagas etc)
* The thunks are responsible only for the dispatching action on AJAX begin/fail and complete.
* Any routing has to be dealt with the receiving component via a promise.
## Keep it Simple Stupid (KISS)
* Essentially, if the component needs no state - use stateless functions.
* Perf matters: **Stateless fns > ES6 class components > React.createClass()**
* Don’t pass any more props than required {...this.props} only if the list is big -- if not pass individual props.
* Too much flows of control (If-else variations) inside the component is usually a red-flag. This most likely means - need to split up the component or create a separate variation.
* Don’t optimize prematurely - Making the current component reusable with current variations known.
## Articles
[Building React Components for Multiple Brands and Applications](https://medium.com/walmartlabs/building-react-components-for-multiple-brands-and-applications-7e9157a39db4)
gitextract_p1p5oxnm/
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.txt
├── READINGS.md
├── README.md
├── SUMMARY.md
├── anti-patterns/
│ ├── 01.props-in-initial-state.md
│ ├── 02.findDOMNode.md
│ ├── 03.mixins.md
│ ├── 04.setState-in-componentWillMount.md
│ ├── 05.mutating-state.md
│ ├── 06.using-indexes-as-key.md
│ ├── 07.spreading-props-dom.md
│ └── README.md
├── book.json
├── coding-style/
│ └── README.md
├── gotchas/
│ ├── 01.pure-render-checks.md
│ ├── 02.synthetic-events.md
│ └── README.md
├── package.json
├── patterns/
│ ├── 1.conditionals-in-jsx.md
│ ├── 10.passing-function-to-setState.md
│ ├── 11.decorators.md
│ ├── 12.feature-flags-using-redux.md
│ ├── 13.component-switch.md
│ ├── 14.reaching-into-a-component.md
│ ├── 15.list-components.md
│ ├── 16.format-text-via-component.md
│ ├── 17.react-fragments.md
│ ├── 18.share-tracking-logic.md
│ ├── 2.async-nature-of-setState.md
│ ├── 3.dependency-injection.md
│ ├── 4.context-wrapper.md
│ ├── 5.event-handlers.md
│ ├── 6.flux-pattern.md
│ ├── 7.one-way-data-flow.md
│ ├── 8.presentational-vs-container.md
│ └── 9.third-party-integration.md
├── perf-tips/
│ ├── 01.shouldComponentUpdate-check.md
│ ├── 02.pure-component.md
│ ├── 03.reselect.md
│ └── README.md
├── styling/
│ ├── 01.stateless-ui-components.md
│ ├── 02.styles-module.md
│ ├── 03.style-functions.md
│ ├── 04.using-npm-modules.md
│ ├── 05.base-component.md
│ ├── 06.layout-component.md
│ ├── 07.typography-component.md
│ ├── 08.HOC-for-styling.md
│ └── README.md
└── ux-variations/
├── 01.composing-variations.md
├── 02.toggle-ui-elements.md
├── 03.HOC-feature-toggles.md
├── 04.HOC-props-proxy.md
├── 05.wrapper-components.md
├── 06.display-order-variations.md
└── README.md
Condensed preview — 58 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (119K chars).
[
{
"path": ".gitignore",
"chars": 19,
"preview": "_book\nnode_modules\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 52,
"preview": "> Your contributions are heartily ♡ welcome. (✿◠‿◠)\n"
},
{
"path": "LICENSE.txt",
"chars": 18542,
"preview": "Creative Commons Attribution 4.0 International\n\n=======================================================================\n"
},
{
"path": "READINGS.md",
"chars": 341,
"preview": "# Related Links\n- [React in Patterns by krasimir](https://github.com/krasimir/react-in-patterns)\n- [React Patterns by pl"
},
{
"path": "README.md",
"chars": 3659,
"preview": "# [React Bits](https://vasanthk.gitbooks.io/react-bits)\n\nA compilation of React Patterns, techniques, tips and tricks.\n\n"
},
{
"path": "SUMMARY.md",
"chars": 3190,
"preview": "# React Bits\n✨ React patterns, techniques, tips and tricks ✨\n\n- Design Patterns and Techniques\n - [Conditional in JSX]("
},
{
"path": "anti-patterns/01.props-in-initial-state.md",
"chars": 1562,
"preview": "# Props in Initial State\nFrom docs:\n> Using props to generate state in getInitialState often leads to duplication of “so"
},
{
"path": "anti-patterns/02.findDOMNode.md",
"chars": 2306,
"preview": "# Refs over findDOMNode()\nUse callback refs over findDOMNode()\n\nNote:\nReact also supports using a string (instead of a c"
},
{
"path": "anti-patterns/03.mixins.md",
"chars": 2539,
"preview": "# Use Higher order components over Mixins\n\n#### Simple Example\n```javascript\n// With Mixin\nvar WithLink = React.createCl"
},
{
"path": "anti-patterns/04.setState-in-componentWillMount.md",
"chars": 724,
"preview": "# setState() in componentWillMount()\nAvoid async initialization in ``componentWillMount()``\n\n``componentWillMount()`` is"
},
{
"path": "anti-patterns/05.mutating-state.md",
"chars": 1430,
"preview": "# Mutating State without setState()\n- Causes state changes without making component re-render.\n- Whenever setState gets "
},
{
"path": "anti-patterns/06.using-indexes-as-key.md",
"chars": 765,
"preview": "# Using indexes as keys\nKeys should be stable, predictable, and unique so that React can keep track of elements.\n\n#### B"
},
{
"path": "anti-patterns/07.spreading-props-dom.md",
"chars": 1465,
"preview": "# Spreading props on DOM elements\nWhen we spread props we run into the risk of adding unknown HTML attributes, which is "
},
{
"path": "anti-patterns/README.md",
"chars": 158,
"preview": "# Anti-patterns\n\nFamiliarizing ourselves with common anti-patterns will help us understand how React works and describe "
},
{
"path": "book.json",
"chars": 283,
"preview": "{\n \"gitbook\": \">3.0.0\",\n \"plugins\": [\"edit-link\"],\n \"pluginsConfig\": {\n \"edit-link\": {\n \"base\": \"https://gith"
},
{
"path": "coding-style/README.md",
"chars": 171,
"preview": "# Coding Style\n\n**Disclaimer:**\n\nThis section is purely to familiarize oneself with different coding styles out there. I"
},
{
"path": "gotchas/01.pure-render-checks.md",
"chars": 3894,
"preview": "# Pure Render Checks\n\nIn order to preserve performance one needs to consider the creation of new entities in the render "
},
{
"path": "gotchas/02.synthetic-events.md",
"chars": 1138,
"preview": "# Synthetic events in React\nInside React event handlers, the event object is wrapped in a SyntheticEvent object.\nThese o"
},
{
"path": "gotchas/README.md",
"chars": 297,
"preview": "# Gotchas\n\nReact is intuitive for the most part, but there are quite a few stumbling points which might catch you by sur"
},
{
"path": "package.json",
"chars": 195,
"preview": "{\n \"name\": \"react-bits\",\n \"version\": \"1.0.0\",\n \"repository\": \"https://github.com/vasanthk/react-bits.git\",\n \"author\""
},
{
"path": "patterns/1.conditionals-in-jsx.md",
"chars": 2533,
"preview": "# Conditionals in JSX\n\nInstead of\n```javascript\nconst sampleComponent = () => {\n return isTrue ? <p>True!</p> : null\n};"
},
{
"path": "patterns/10.passing-function-to-setState.md",
"chars": 1518,
"preview": "# Passing a function to setState\n\nHere’s the dirty secret about setState — it’s actually asynchronous.\nReact batches sta"
},
{
"path": "patterns/11.decorators.md",
"chars": 1413,
"preview": "# Decorators\nDecorators (*supported by Babel, in Stage 2 proposal as of 03/17*)\n\nIf you’re using something like mobx, yo"
},
{
"path": "patterns/12.feature-flags-using-redux.md",
"chars": 3066,
"preview": "# Feature Flags\nEnabling Feature flags in React using Redux\n\n```javascript\n// createFeatureFlaggedContainer.js\nimport Re"
},
{
"path": "patterns/13.component-switch.md",
"chars": 777,
"preview": "# The switching component\nA switching component is a component that renders one of many components.\n\nUse an object to ma"
},
{
"path": "patterns/14.reaching-into-a-component.md",
"chars": 1054,
"preview": "# Reaching into a Component\nAccessing a component from the parent.\neg. Autofocus an input (controlled by parent componen"
},
{
"path": "patterns/15.list-components.md",
"chars": 816,
"preview": "# Lists Components\nLists and other things that are almost components\n\nInstead of making a separate component for lists I"
},
{
"path": "patterns/16.format-text-via-component.md",
"chars": 2511,
"preview": "# Components for formatting text\nInstead of formatting text by calling helper functions inside render, we can create a s"
},
{
"path": "patterns/17.react-fragments.md",
"chars": 824,
"preview": "# React Fragments\n\nReact fragments are used whenever a component needs returned with multiple children.\n\nSpecifically, f"
},
{
"path": "patterns/18.share-tracking-logic.md",
"chars": 950,
"preview": "# Share Tracking Logic\nUsing HOC to share tracking logic across various UX components\n\neg. Adding analytics tracking acr"
},
{
"path": "patterns/2.async-nature-of-setState.md",
"chars": 5977,
"preview": "# Async Nature Of setState()\nOn the Async nature of setState()\n\n## Gist:\nReact batches updates and flushes it out once p"
},
{
"path": "patterns/3.dependency-injection.md",
"chars": 3344,
"preview": "# Dependency Injection\n\nIn React the need of [dependency injection](https://www.youtube.com/watch?v=IKD2-MAkXyQ) is easi"
},
{
"path": "patterns/4.context-wrapper.md",
"chars": 5429,
"preview": "# Context Wrapper\nIt is a good practice that our context is not just a plain object but it has an interface that allows "
},
{
"path": "patterns/5.event-handlers.md",
"chars": 2825,
"preview": "# Event Handlers\nBinding event handlers in the constructor.\n\nMost of the times we handle DOM events in the component tha"
},
{
"path": "patterns/6.flux-pattern.md",
"chars": 2188,
"preview": "# Flux pattern for data handling\n\n**Simple dispatcher**\n```javascript\nvar Dispatcher = function () {\n return {\n _sto"
},
{
"path": "patterns/7.one-way-data-flow.md",
"chars": 1973,
"preview": "# One way data flow\n\nOne-way direction data flow eliminates multiple states and deals with only one which is usually ins"
},
{
"path": "patterns/8.presentational-vs-container.md",
"chars": 3856,
"preview": "# Presentational and Container components\n\n#### Problem\nData and logic together.\n```javascript\nclass Clock extends React"
},
{
"path": "patterns/9.third-party-integration.md",
"chars": 2855,
"preview": "# Third Party Integration\nMixing 3rd party integrations/libraries with React\n\nIn this example we'll see how to mix React"
},
{
"path": "perf-tips/01.shouldComponentUpdate-check.md",
"chars": 2339,
"preview": "# shouldComponentUpdate() check\n`shouldComponentUpdate` check to avoid expensive re-renders\n\nReact Components re-render "
},
{
"path": "perf-tips/02.pure-component.md",
"chars": 1573,
"preview": "# Using Pure Components\nPure Components do shallow equality checks in `shouldComponentUpdate` by default. This is intend"
},
{
"path": "perf-tips/03.reselect.md",
"chars": 1371,
"preview": "# Using reselect\nUse Reselect in Redux connect(mapState) -- to avoid frequent re-render.\n\n#### Bad\n```javascript\nlet App"
},
{
"path": "perf-tips/README.md",
"chars": 774,
"preview": "# Perf Tips\n\n**Key Ideas**\n\n- Avoid Reconciliation with shouldComponentUpdate() check\n\n- Use Immutable Data Structures\n\n"
},
{
"path": "styling/01.stateless-ui-components.md",
"chars": 1414,
"preview": "# Styling in stateless UI components\nKeep styles separated from the parts of the app that are tied to state.\nThat means "
},
{
"path": "styling/02.styles-module.md",
"chars": 1117,
"preview": "# Styles module\nGenerally, hard coding styles values in a component should be avoided.\nAny values that are likely to be "
},
{
"path": "styling/03.style-functions.md",
"chars": 1367,
"preview": "# Style Functions\nSince we’re using JavaScript, we can also employ helper functions for styling elements.\n\n#### Example "
},
{
"path": "styling/04.using-npm-modules.md",
"chars": 563,
"preview": "# Using npm modules\nFor more complex color/style transformation logic, it's always good to use it from a separate npm mo"
},
{
"path": "styling/05.base-component.md",
"chars": 1597,
"preview": "# Base Component\n### Using a Base Component\nThere is tremendous amount of flexibility when it comes to composition in Re"
},
{
"path": "styling/06.layout-component.md",
"chars": 1465,
"preview": "# Layout component\nWe can extend the idea of [Base components](./05.base-component.md) to create Layout components.\n\n###"
},
{
"path": "styling/07.typography-component.md",
"chars": 1380,
"preview": "# Typography Component\nWe can extend the idea of [Base components](./05.base-component.md) to create Typography componen"
},
{
"path": "styling/08.HOC-for-styling.md",
"chars": 2724,
"preview": "# Using HOC for styling\nSometimes there are isolated UI components that only require a minimal amount of state for inter"
},
{
"path": "styling/README.md",
"chars": 503,
"preview": "# Styling in React\n\nHere we look into some ideas around using CSS in JS.\n\nIf you are pondering over why to use CSS in JS"
},
{
"path": "ux-variations/01.composing-variations.md",
"chars": 1853,
"preview": "# Using Composition to handle UX variations\nCombining smaller reusable components to build a bigger UI blocks.\n\n**How do"
},
{
"path": "ux-variations/02.toggle-ui-elements.md",
"chars": 1117,
"preview": "# Toggle UI Elements\nHandling minor UX variations in the component by toggling ON/OFF features.\n\nModify the component to"
},
{
"path": "ux-variations/03.HOC-feature-toggles.md",
"chars": 545,
"preview": "# HOC for Feature Toggles\nUsing Higher order components (HOC) for UX variations\n\neg. Toggling features On/Off\n\n```javasc"
},
{
"path": "ux-variations/04.HOC-props-proxy.md",
"chars": 429,
"preview": "# Higher Order Component - Props proxy\nThis basically helps to add/edit props passed to the Component.\n\n```javascript\nfu"
},
{
"path": "ux-variations/05.wrapper-components.md",
"chars": 1263,
"preview": "# Wrapper Components\nUsing Wrappers to handle UX/style variations\n\nFor Handling Wrapper ``<div>``’s and other markup aro"
},
{
"path": "ux-variations/06.display-order-variations.md",
"chars": 668,
"preview": "# Display UI elements in different order\n\nUse a prop to specify order – Map through ReactElements and render it based on"
},
{
"path": "ux-variations/README.md",
"chars": 1622,
"preview": "# Handling UX variations for multiple brands and apps\n\n\n## [Slides from my talk](https://speakerdeck.com/vasa/building-m"
}
]
About this extraction
This page contains the full source code of the vasanthk/react-bits GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 58 files (109.7 KB), approximately 28.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.