Reputation: 15
I have a basic app which simply returns a number of cards with some content inside, I have some buttons which then filter the returned cards by a value found in the dataset. The filter buttons do work indididually but if I click one after the other the filter is being applied to the now filtered data. How can I make sure the filter is being applied to the initial state of the data or how can I reset the state to everything before the filter is applied? Thanks.
parent.js
import './App.scss';
import DataThoughts from "./assets/data/DataThoughts";
import Thoughts from "./components/Thoughts";
function AppThoughts() {
return (
<div className="App">
<main className={'bg-light'}>
<div className={'container'}>
<Thoughts data={DataThoughts} />
</div>
</main>
</div>
);
}
export default AppThoughts;
Thoughts.js
import React, { Component } from 'react';
import FilterButton from "./FilterButton";
class Thoughts extends Component {
constructor(props) {
super(props);
this.state = {...props};
}
handleClick = value => () => {
let filtered = this.state.data.filter(item => item.Emotion === value);
this.setState({ data: filtered });
console.log(this.state.data);
};
render() {
let data = this.state.data;
let numberOfThoughts = data.length;
let dataList = this.state.data.map((thought, i) =>
<div className={`col-12 col-sm-12 col-md-6 ${i % 2 === 0 ? i % 3 === 0 ? 'col-lg-3 col-xl-3' : 'col-lg-5 col-xl-5' : 'col-lg-4 col-xl-4'}`} key={'thought'+i}>
<div className="card mb-4">
{thought.Photo ? <img src={thought.Photo} className="card-img-top" alt={thought.Emotion}/> : ''}
<div className="p-5">
<blockquote className="blockquote mb-0">
<p className={'small text-muted'}>{thought.Date}</p>
<p className={`${i % 2 === 0 ? i % 3 === 0 ? 'display-6' : 'display-4' : 'display-5'} mb-4`}>{thought.Thought}</p>
<footer className="small text-muted">{thought.Author}, <cite title="Source Title">{thought.Location}</cite></footer>
</blockquote>
</div>
</div>
</div>
);
return (
<section className="row section-row justify-content-start thoughts">
<div className={`col-12`} key={'filters'}>
<FilterButton buttonText={"Happy"} onClick={this.handleClick('Happy')} />
<FilterButton buttonText={"Sad"} onClick={this.handleClick('Sad')} />
<FilterButton buttonText={"Thinking"} onClick={this.handleClick('Thinking')} />
<FilterButton buttonText={"All"} onClick={this.handleClick('All')} />
</div>
{dataList}
<div className={`col-12 col-sm-12 col-md-6 col-lg-2 col-xl-2 d-flex align-items-center justify-content-center`} key={'total'}>
<span className={'display-1'}>{numberOfThoughts}</span>
</div>
</section>
);
}
}
Thoughts.defaultProps = {
Photo: '',
Emotion:'Happy',
Date:'Morning',
Thought:'Default',
Author:'Me',
Location:'Somewhere'
};
export default Thoughts; // Don’t forget to use export default!
FilterButtons.js
import React, { Component } from 'react';
class FilterButton extends Component {
render() {
return (
<button className={'btn btn-primary d-inline-block mb-4'} onClick={this.props.onClick}>{this.props.buttonText}</button>
);
}
}
export default FilterButton; // Don’t forget to use export default!
Upvotes: 1
Views: 2004
Reputation: 12665
It looks like the initial data comes from the props. You can access the props with this.props
. So you can do something like this:
handleClick = value => () => {
// filter the initial data
let filtered = this.props.data.filter(item => item.Emotion === value);
this.setState({ data: filtered });
// set to initial data
// this.setState({ ...this.props });
console.log(this.state.data);
};
Upvotes: 1