react-reduce
v0.2.0
Published
React transformer
Downloads
121
Readme
react-reduce
Sometimes there is a need in "react" to implement filters in our application. The most common task of a filter is to filter the received list. The react-reduce
module provides a convenient filter set-up, while providing a separation between the displayed list and the filtering mechanism.
example usage
1. Create transformer, define filters
import React from 'react';
import { Transform } from 'react-reduce';
import ModeFilter from './filters/mode-filter.component';
import PriceFilter from './filters/price-filter.component';
export default () => {
const products = [
{ mode: 'virtual', price: 10, name: 'product 1' },
{ mode: 'virtual', price: 50, name: 'product 2' },
{ mode: 'virtual', price: 500, name: 'product 3' },
{ mode: 'virtual', price: 1000, name: 'product 4' },
{ mode: 'real', price: 20, name: 'product 5' },
{ mode: 'real', price: 80, name: 'product 6' },
{ mode: 'real', price: 200, name: 'product 7' },
{ mode: 'real', price: 400, name: 'product 8' },
];
return (
<Transform
toTransform={products}
transformers={['modeFilter', 'priceFilter']}
>
{({ response: filteredProducts, refs, onChange }) => (
<React.Fragment>
<ModeFilter ref={refs.modeFilter} onChange={onChange}/>
<PriceFilter ref={refs.priceFilter} onChange={onChange}/>
<pre>{JSON.stringify(filteredProducts, null, '\t')}</pre>
</React.Fragment>
)}
</Transform>
);
};
2. Define filters
Each filter should have a transform
method, which will be fired (under the hood) after each filter change. The purpose of this method is to prepare a list according to the state of the filter.
Due to the fact that each filter can have a different form - I keep implementing the onChange
function and preparing the state for self-implementation. It is important that the self-implemented onChange
function should run the `onChange function passed in the props.
2.1. Example implementation of mode filter mechanism
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class ModeFilter extends Component {
static propTypes = {
onChange: PropTypes.func,
defaultValue: PropTypes.string,
};
static defaultProps = {
onChange: () => {},
value: 'all',
};
state = ModeFilter.defaultProps;
render() {
return (
<select
value={this.state.value}
onChange={event => this._onChange(event)}
>
<option value="all">all</option>
<option value="virtual">virtual</option>
<option value="real">real</option>
</select>
);
}
transform(list) {
return (this.state.value === 'all') ? list : (
list.filter(element => element.mode === this.state.value)
);
}
_onChange(event) {
const { value } = event.target;
this.setState({ value }, () => this.props.onChange(value));
}
}
2.2. Example implementation of price filter mechanism
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class PriceFilter extends Component {
static propTypes = {
onChange: PropTypes.func,
defaultValue: PropTypes.string,
};
static defaultProps = {
onChange: () => {},
value: 'all',
};
state = ModeFilter.defaultProps;
render() {
return (
<select
value={this.state.value}
onChange={event => this._onChange(event)}
>
<option value="all">all</option>
<option value="less">price less than 100</option>
<option value="greater">price greater than 100</option>
</select>
);
}
transform(list) {
if (this.state.value === 'all') {
return list;
}
if (this.state.value === 'less') {
return list.filter(element => (element.price < 100));
} else if (this.state.value === 'greater') {
return list.filter(element => (element.price > 100));
}
}
_onChange(event) {
const { value } = event.target;
this.setState({ value }, () => this.props.onChange(value));
}
}