Skip to content

Instantly share code, notes, and snippets.

@mki
Last active February 5, 2020 20:14
Show Gist options
  • Save mki/b881e0c5318ce0dfc8184747bdd62c52 to your computer and use it in GitHub Desktop.
Save mki/b881e0c5318ce0dfc8184747bdd62c52 to your computer and use it in GitHub Desktop.
React example code
/*
1. For react we made this gist. It is worth noting that the project uses the old version of the react
and in this example the componentWillReceiveProps (newProps) method is specified,
which will stop working in the 17th version of the react.
We refactored ViewedSlider.js for an example of switching to version 17.
2. I am attaching a small video of the test.customorrow.com project, which is made on Vue.js.
It demonstrates our experience in js, even if not in the organization of the project,
but the approach itself is important. While coding on vue.js we understand some things at react.
You can pause and watch the code. https://yadi.sk/i/u1oJrgZNZ_bOeA
The project uses the https://www.npmjs.com/package/redux-restify library,
I think it will be interesting to get acquainted with it (it is based on redux)
This code is used for one of the old projects. It's a good thing we still have it.
*/
import React, { Component } from 'react';
import ViewedSlider from './ViewedSlider.js';
import CatalogSideBar from './CatalogSideBar.js';
import CatalogList from './CatalogList.js';
import PathCatalog from './PathCatalog.js';
import '../css/style-catalogue.css';
class Catalog extends Component {
constructor(props) {
super(props);
this.state = {
filters: {},
setFilters: {
type: '',
color: '',
season: '',
reason: '',
discounted: false,
categoryId: '',
size: [],
heelSize: [],
minPrice: 0,
maxPrice: 60000,
brand: '',
},
sortBy: 'price',
updatePrices: false,
};
}
componentWillMount() {
this.setState({ setFilters: this.props.setFilters });
this.setState({ filters: this.props.filters });
}
componentWillReceiveProps(newProps) {
this.setState({ setFilters: newProps.setFilters });
this.setState({ filters: newProps.filters });
}
updateData = value => {
const filterState = this.state.setFilters;
if (typeof value === 'object') {
for (const key in value) {
filterState[key] = value[key];
}
this.setState({ setFilters: filterState });
} else {
this.setState({ sortBy: value });
}
};
render() {
return (
<main className="product-catalogue clearfix">
<PathCatalog {...this.props} />
<CatalogSideBar
updateData={this.updateData}
deleteData={this.deleteData}
type={this.state.filters.type}
color={this.state.filters.color}
size={this.state.filters.sizes}
heelSize={this.state.filters.heelSize}
reason={this.state.filters.reason}
season={this.state.filters.season}
brand={this.state.filters.brand}
minPrice={this.state.setFilters.minPrice}
maxPrice={this.state.setFilters.maxPrice}
setFilters={this.state.setFilters}
/>
<CatalogList
{...this.props}
{...this.state}
updateSort={this.updateData}
setFilters={this.props.setFilters}
/>
<ViewedSlider {...this.props} {...this.state} />
</main>
);
}
}
export default Catalog;
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import PropTypes from 'prop-types';
import CatalogSideBarBrand from './CatalogSideBarBrand.js';
import CatalogSideBarColor from './CatalogSideBarColor.js';
import CatalogSideBarHeelSize from './CatalogSideBarHeelSize.js';
import CatalogSideBarReason from './CatalogSideBarReason.js';
import CatalogSideBarSeason from './CatalogSideBarSeason.js';
import CatalogSideBarSize from './CatalogSideBarSize.js';
import CatalogSideBarType from './CatalogSideBarType.js';
import CatalogSideBarPrice from './CatalogSideBarPrice.js';
class CatalogSideBar extends Component {
constructor(props) {
super(props);
this.state = {
setFilters: {
type: '',
color: '',
season: '',
reason: '',
discounted: false,
size: [],
heelSize: [],
minPrice: 0,
maxPrice: 60000,
brand: '',
},
};
}
static get propTypes() {
return {
type: PropTypes.instanceOf(Array),
color: PropTypes.instanceOf(Array),
heelSize: PropTypes.instanceOf(Array),
reason: PropTypes.instanceOf(Array),
season: PropTypes.instanceOf(Array),
size: PropTypes.instanceOf(Array),
brand: PropTypes.instanceOf(Array),
discounted: PropTypes.bool,
minPrice: PropTypes.number,
maxPrice: PropTypes.number,
updateData: PropTypes.func.isRequired
};
}
static get defaultProps() {
return {
type: [],
color: [],
season: [],
reason: [],
discounted: false,
size: [],
heelSize: [],
minPrice: 0,
maxPrice: 60000,
brand: [],
};
}
componentWillMount() {
this.setState({ setFilters: this.props.setFilters });
this.setState({ filters: this.props.filters });
}
componentWillReceiveProps(newProps) {
this.setState({ setFilters: newProps.setFilters });
this.setState({ filters: newProps.filters });
}
componentWillUnmount(){
this.clearFilters()
}
updateData = (filter, data) => {
const filterState = this.state.setFilters;
filterState[filter] = data;
this.setState({ setFilters: filterState });
this.props.updateData(this.state.setFilters);
}
clearFilters = () => {
const filterState = this.state.setFilters;
for (const key in filterState) {
filterState[key] = '';
}
filterState.minPrice = 0;
filterState.maxPrice = 60000;
this.setState({ setFilters: filterState });
this.props.updateData(this.state.setFilters);
Array.from(document.querySelectorAll('.filter-active')).forEach(elem => elem.classList.remove('filter-active'));
Array.from(document.querySelectorAll('.list-filter :checked')).forEach(elem => elem.checked = false);
}
opener = (event, ref) => {
const elem = event.currentTarget;
if (elem.classList.contains('opener-down')) {
elem.classList.remove('opener-down');
elem.classList.add('opener-up');
ref.classList.add('filter-hidden');
return null;
}
if (elem.classList.contains('opener-up')) {
elem.classList.remove('opener-up');
elem.classList.add('opener-down');
ref.classList.remove('filter-hidden');
return null;
}
}
render() {
return (
<section className="sidebar">
<CatalogSideBarType
type={this.props.type}
updateFilter={this.updateData}
setType={this.props.setFilters.type}
/>
<div className="separator-150 separator-150-1" />
<CatalogSideBarPrice
minPrice={this.props.minPrice}
maxPrice={this.props.maxPrice}
updateFilter={this.updateData}
opener={this.opener}
/>
<div className="separator-150 separator-150-2" />
<CatalogSideBarColor
color={this.props.color}
updateFilter={this.updateData}
opener={this.opener}
/>
<div className="separator-150 separator-150-3" />
<CatalogSideBarSize
size={this.props.size}
updateFilter={this.updateData}
opener={this.opener}
/>
<div className="separator-150 separator-150-4" />
<CatalogSideBarHeelSize
heelSize={this.props.heelSize}
updateFilter={this.updateData}
opener={this.opener}
/>
<div className="separator-150 separator-150-5" />
<CatalogSideBarReason
reason={this.props.reason}
updateFilter={this.updateData}
opener={this.opener}
setReason={this.props.setFilters.reason}
/>
<div className="separator-150 separator-150-6" />
<CatalogSideBarSeason
season={this.props.season}
updateFilter={this.updateData}
opener={this.opener}
setSeason={this.props.setFilters.season}
/>
<div className="separator-150 separator-150-7" />
<CatalogSideBarBrand brand={this.props.brand} updateFilter={this.updateData} />
<section className="sidebar__division">
<div className="drop-down">
<NavLink to="#" onClick={this.clearFilters}>
<span className="drop-down-icon" />
Сбросить
</NavLink>
</div>
</section>
</section>
);
}
}
export default CatalogSideBar;
import React, { Component } from 'react';
import ViewedItem from './ViewedItem.js';
class ViewedSlider extends Component {
constructor(props) {
super(props);
this.slide = [];
this.arr = [];
this.state = {
items: [],
index: 0
};
}
componentDidMount() {
this.getViewItems();
}
componentDidUpdate(prevProps, prevState) {
if (localStorage.viewedItems) {
const viewedGoodsIds = JSON.parse(localStorage.viewedItems).map(item => item.id);
const isGoodsInState = viewedGoodsIds
.every(id => prevState.items.some(item => item.id === id));
if (!isGoodsInState) {
this.getViewItems();
this.slider(this.state);
}
}
if (this.state.items.length < 6) {
const arrow = document.querySelectorAll('.overlooked-slider__arrow');
Array.from(arrow).forEach(item => item.classList.add('hidden'))
} else {
const arrow = document.querySelectorAll('.overlooked-slider__arrow');
Array.from(arrow).forEach(item => item.classList.remove('hidden'))
}
}
getViewItems() {
if (localStorage.viewedItems !== undefined) {
this.setState({ items: JSON.parse(localStorage.viewedItems) });
this.setState({ index: 0 });
this.slider(this.state);
}
}
slider(props) {
if (props.items.length) {
this.slide = props.items.map(item => ({
id: item.id,
img: item.images[0]
}));
this.slide.length = this.slide.length < 5 ? 5 : this.slide.length
}
}
onClickHandlerNextSlider = () => {
let step = this.state.index + 1;
if (this.state.index === this.state.items.length - 1) {
step = 0;
}
this.setState({ index: step })
}
onClickHandlerPrevSlider = () => {
let step = this.state.index - 1;
if (!this.state.index) {
step = this.state.items.length - 1;
}
this.setState({ index: step })
}
render() {
if (localStorage.viewedItems === undefined) return null;
return (
<section className="product-card__overlooked-slider clearfix">
<h3>Вы смотрели:</h3>
<div className="overlooked-slider">
<div className="overlooked-slider__arrow overlooked-slider__arrow_left arrow"
onClick={ this.onClickHandlerPrevSlider }></div>
<ViewedItem item={ this.slide[this.state.index % this.slide.length] }/>
<ViewedItem item={ this.slide[(this.state.index + 1) % this.slide.length] }/>
<ViewedItem item={ this.slide[(this.state.index + 2) % this.slide.length] }/>
<ViewedItem item={ this.slide[(this.state.index + 3) % this.slide.length] }/>
<ViewedItem item={ this.slide[(this.state.index + 4) % this.slide.length] }/>
<div className="overlooked-slider__arrow overlooked-slider__arrow_right arrow"
onClick={ this.onClickHandlerNextSlider }></div>
</div>
</section>
);
}
}
export default ViewedSlider;
import React from 'react';
const withData = (endpoint, propName) => Component => class extends React.Component {
static get displayName() {
const name = Component.displayName || Component.name || 'Component';
return `WithData(${name})`;
}
constructor(props) {
super(props);
this.state = {
[propName]: undefined
};
}
componentDidMount() {
this.fetchData(this.props);
}
componentWillReceiveProps(nextProps) {
this.fetchData(nextProps);
}
fetchData(props) {
if (typeof endpoint === 'function') {
endpoint = endpoint(props);
}
fetch(endpoint)
.then(res => (res.status === 200 ? res : new Error(res)))
.then((res) => { document.querySelector('.loading').classList.add('hidden'); return res; })
.then(res => res.json())
.then(res => (res.status === 'ok' ? res.data : new Error(res.status)))
.then(data => (this.setState({ [propName]: data })))
.catch((error) => { console.log('error', error); });
}
render() {
return <Component {...this.props} {...this.state} />;
}
};
export default withData;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment