As we know, the structure of a class component can be simplified as the following:
// Blank 1
class Books extends Component {
// Blank 2
render(){
// Blank 3
return()
}
export default Books;
So just for example:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { updateFilters } from '../../../services/filters/actions';
import Checkbox from '../../Checkbox';
import GithubStarButton from '../../github/StarButton';
import './style.scss';
const availableSizes = ['XS', 'S', 'M', 'ML', 'L', 'XL', 'XXL'];
class Filter extends Component {
static propTypes = {
updateFilters: PropTypes.func.isRequired,
filters: PropTypes.array
};
componentWillMount() {
this.selectedCheckboxes = new Set();
}
toggleCheckbox = label => {
if (this.selectedCheckboxes.has(label)) {
this.selectedCheckboxes.delete(label);
} else {
this.selectedCheckboxes.add(label);
}
this.props.updateFilters(Array.from(this.selectedCheckboxes));
};
createCheckbox = label => (
<Checkbox
classes="filters-available-size"
label={label}
handleCheckboxChange={this.toggleCheckbox}
key={label}
/>
);
createCheckboxes = () => availableSizes.map(this.createCheckbox);
render() {
return (
<div className="filters">
<h4 className="title">Sizes:</h4>
{this.createCheckboxes()}
<GithubStarButton />
</div>
);
}
}
const mapStateToProps = state => ({
filters: state.filters.items
});
export default connect(
mapStateToProps,
{ updateFilters }
)(Filter);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { fetchProducts } from '../../services/shelf/actions';
import { addProduct } from '../../services/cart/actions';
import Product from './Product';
import Filter from './Filter';
import ShelfHeader from './ShelfHeader';
import Clearfix from '../Clearfix';
import Spinner from '../Spinner';
import './style.scss';
class Shelf extends Component {
static propTypes = {
fetchProducts: PropTypes.func.isRequired,
products: PropTypes.array.isRequired,
addProduct: PropTypes.func.isRequired,
filters: PropTypes.array,
sort: PropTypes.string
};
state = {
loading: false
};
componentWillMount() {
const { filters, sort } = this.props;
this.handleFetchProducts(filters, sort);
}
componentWillReceiveProps(nextProps) {
const { filters: nextFilters, sort: nextSort } = nextProps;
if (nextFilters !== this.props.filters) {
this.handleFetchProducts(nextFilters, undefined);
}
if (nextSort !== this.props.sort) {
this.handleFetchProducts(undefined, nextSort);
}
}
handleFetchProducts = (
filters = this.props.filters,
sort = this.props.sort
) => {
this.setState({ loading: true });
this.props.fetchProducts(filters, sort, () => {
this.setState({ loading: false });
});
};
render() {
const { products } = this.props;
const p = products.map(p => {
return (
<Product product={p} addProduct={this.props.addProduct} key=
{p.id} />
);
});
return (
<React.Fragment>
{this.state.loading && <Spinner />}
<Filter />
<div className="shelf-container">
<ShelfHeader productsLength={products.length} />
{p}
<Clearfix />
</div>
<Clearfix />
</React.Fragment>
);
}
}
const mapStateToProps = state => ({
products: state.shelf.products,
filters: state.filters.items,
sort: state.sort.type
});
export default connect(
mapStateToProps,
{ fetchProducts, addProduct }
)(Shelf);
Except for state and life cycle methods, sometimes we define other types of attributes and functions in Blank 1, sometimes in Blank 2, sometimes in Blank 3. So I am wondering when we are going to define attributes and functions, which part should we choose? Is there a convention or something like that?