ALTERNATE PATTERNS FOR REUSABILITY IN REACT
ESPEN HENRIKSEN
@espen_dev
@esphen
Components
Components are the primary unit of code reuse in React
Advantages
- The first thing you learn in React
- Pretty easy to understand
Case:
You want to fetch something from a server and show a loading spinner
Loading component
// SomeComponent.js
import React from 'react';
import Loading from './LoadingComponent';
export default props => {
if (props.loading) <Loading />;
return <div>{props.data}</div>;
};
// LoadingComponent.js
import React from 'react';
export default () => <i className="fa fa-spinner fa-spin" />;
Issues with "LoadingComponent"
- Imperative rendering
- Cognitive overhead in render
- Bad solution for cross-cutting concerns
Higher order components
Use HOCs For Cross-Cutting Concerns
a higher-order component is a function that takes a component and returns a new component
const EnhancedComponent = higherOrderComponent(WrappedComponent);
Why?
Advantages
- Encourages functional components
- Composition
- Makes components testable
Case:
You want to fetch something from a server and show a loading spinner
import React from 'react';
import { compose } from 'recompose';
import fetch from 'fetch-hoc';
import { withLoading, withError } from './loading';
export const FooComponent props => (
<div>{props.data}</div>
);
export default compose(
fetch('/some/data'),
withLoading,
withError('Failed to fetch that stuff'),
)(FooComponent);
Component can focus on rendering the data
export const FooComponent props => <div>{props.data}</div>;
// react-apollo
export const GraphQLComponent = graphql(gql`
query MyQuery {
todos { text }
}
`)(FooComponent);
// react-router
export const ReactRouterComponent = withRouter(FooComponent);
// recompose
export const StatefulFunctionalComponent = compose(
withState('count', 'setCount', 0),
withHandlers({
incrementCount: props => () => {
props.setCount(props.count + 1);
},
}),
)(FooComponent);
// redux & fetch-hoc
export const ComponentWithData = fetch(
connect(state => ({ userId: state.user.id })),
fetch(props => `/user/${props.userId}/cart`),
)(FooComponent);
fetch-hoc
github.com/esphen/fetch-hoc
Tagged template literals
an API that makes many tasks related to creating and parsing strings simple
Tagged template literals
var person = 'Mike';
var age = 28;
function myTag(strings, personExp, ageExp) {
var str0 = strings[0]; // "that "
var str1 = strings[1]; // " is a "
var ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
} else {
ageStr = 'youngster';
}
return str0 + personExp + str1 + ageStr;
}
var output = myTag`that ${person} is a ${age}`;
console.log(output);
// that Mike is a youngster
Why?
- String formatting
- Can output anything
- Makes new patterns possible
import React from 'react';
import f from 'format';
export const Texts = props => (
f`Hello ${props.name}, you have ${props.amount}:cur(NOK) in your bank account.`
);
export const UserInfo = props => (
<ul>
<li>{f`Username: ${props.username}:uid`}</li>
<li>{f`You have ${props.pets}:num unread messages`}</li>
</ul>
);
A hypothetical formatting library
styled-components
A library for css-in-js
styled-components
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
color: white;
/* "Change styling" based on props */
${props => props.primary && css`
background: white;
color: palevioletred;
`}
`
export default () => [
<Button />
<Button primary />
];
i18n
Compiler/bundler plugins
- Bullet One
- Bullet Two
- Bullet Three
Advantages
- No runtime overhead
- Global reach
- AOT optimizations
- Performance
webpack-i18n-plugin
import React from 'react';
const selectFruit = () => {
alert(__('You selected a fruit. Good on you!'));
};
export default props => (
<form onSubmit={selectFruit}>
{__('Choose fruit')}
<input type="text" placeholder={__('Fruit')} />
</form>
);
Portals
- Bullet One
- Bullet Two
- Bullet Three
Codemods
- Bullet One
- Bullet Two
- Bullet Three
Don't be afraid to think outside the box
Questions?
slides.com/esphen/alternate-patterns-for-reusability
Alternate patterns for reusability in react
By Eline H
Alternate patterns for reusability in react
- 33