Skip to content

Instantly share code, notes, and snippets.

@dtothefp
Last active August 23, 2017 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dtothefp/1a10f300749960ba64c50ce4eceec458 to your computer and use it in GitHub Desktop.
Save dtothefp/1a10f300749960ba64c50ce4eceec458 to your computer and use it in GitHub Desktop.
// HOC and context
// provide context with HOC
import App from './components/App';
import ProvideContext from './containers/ProvideContext';
const transportationTypes = [
'armored car',
'fire engine',
'golf cart',
'hyperloop'
];
const elm = document.getElementById('app');
const Component = (
<ProvideContext types={transportationTypes}>
<App />
</ProvideContext>
);
render(Component, elm);
// receive context with HOC
import TypeListItem from './TypeListItem';
import contextToProps from '../containers/contextToProps';
class TransportationList extends Component {
render() {
return (
<ul>
{this.props.types.map((type, i) => (
<TypeListItem
key={`type_${i}`}
type={type}
/>
))}
</ul>
);
}
}
const propTypes = {
types: PropTypes.array.isRequired
};
TransportationList.propTypes = propTypes;
export default contextToProps(TransportationList, propTypes);
// provide context container
import {Children, Component} from 'react';
import PropTypes from 'prop-types';
class ProvideContext extends Component {
getChildContext() {
return {types: this.props.types};
}
render() {
return Children.only(this.props.children);
}
}
ProvideContext.propTypes = {
types: PropTypes.array.isRequired,
children: PropTypes.element.isRequired
};
ProvideContext.childContextTypes = {
types: PropTypes.array.isRequired
};
export default ProvideContext;
// HOC to receive context
import {createElement, Component} from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
export default function(ChildComponent, dataBindings) {
class ContextToProps extends Component {
render() {
const mergedProps = Object.assign(
{},
this.state,
this.context,
this.props
);
return createElement(ChildComponent, mergedProps);
}
}
ContextToProps.contextTypes = dataBindings;
hoistNonReactStatics(ContextToProps, ChildComponent);
return ContextToProps;
}
// setting state and using forms
import FormFilter from './FormFilter';
import TypeList from './TypeList';
class App extends Component {
constructor(props) {
super(props);
this.state = {
types: props.types,
value: ''
};
this.filterTypes = this.filterTypes.bind(this);
}
filterTypes(value) {
const {types} = this.props;
const filterVal = value.toLowerCase();
const matchedTypes = types.filter(type => {
return type.toLowerCase().startsWith(filterVal);
});
this.setState({
types: matchedTypes,
value
});
}
render() {
const {types, value} = this.state;
return (
<div className="container">
<div className="row">
<FormFilter
handleChange={this.filterTypes}
value={value}
/>
<TypeList types={types}/>
</div>
</div>
);
}
}
export default App;
// bootstrap
import App from './components/App';
const elm = document.getElementById('app');
const transportationTypes = [
'armored car',
'fire engine',
'golf cart',
'hyperloop'
];
render(
<App
types={transportationTypes}
/>,
elm
);
// form filter
import React from 'react';
import PropTypes from 'prop-types';
const FormFilter = ({
handleChange,
value
}) => {
return (
<div className="col">
<form>
<input
type="text"
name="filter"
placeholder="Filter Types"
value={value}
onChange={e => handleChange(e.target.value)}
/>
</form>
</div>
);
};
FormFilter.propTypes = {
handleChange: PropTypes.func.isRequired,
value: PropTypes.string.isRequired
};
export default FormFilter;
// local styles
import cx from 'classnames';
import styles from './ListStyles.scss';
const TypeListItem = (props) => {
const {type, index} = props;
const styleKey = index % 2 === 0 ? 'even' : 'odd';
const className = cx(styles[styleKey], {
active: type === 'hyperloop'
});
return <li className={className}>{type}</li>;
};
TypeListItem.propTypes = {
index: PropTypes.number.isRequired,
type: PropTypes.string.isRequired
};
export default TypeListItem;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment