Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
65
rated 0 times [  68] [ 3]  / answers: 1 / hits: 24254  / 5 Years ago, mon, july 29, 2019, 12:00:00

Upon clicking a filter button, the first filter returns the correct data, but the array in state is mutated (or destroyed?) when a second filter method is called. I'm using setState for each function and cannot figure out why the array's initial state is not restored.



This app is working when I import a local copy of the JSON data. The blocks of commented code do indeed show that the filter functions work with the local data, but not with the same JSON data returned by the fetch method from my server.



import React from react;
import { Button, Row, Col } from react-bootstrap;
import AutoList from './AutoList';
// import autoData from '../autoData.json';

const API = https://MY_SERVER/autoData.json;

class GetAutos extends React.Component {
constructor(props) {
super(props);

this.state = {
autos: [],
};
}

fetchAutoData() {
fetch(API)
.then(autoData => autoData.json())
.then(autoData =>
this.setState({
autos: autoData,
isLoading: false,
})
)
.catch(error => this.setState({ error, isLoading: false }));

}

componentDidMount() {
this.fetchAutoData();
// this.setState(() => ({ autos: autoData }));
}


render() {

const { autos } = this.state;

let onResetArray = () => {
this.setState({ autoData: this.state.autos })
//console.log(autos)
}

let filterFord = () => {
const fordAutos = autos.filter( (auto) => auto.title.includes(Ford));
// const fordAutos = autoData.filter( (auto) => auto.title.includes(Ford));

this.setState({ autos: fordAutos });
}


let filterChevy = () => {
const chevyAutos = autos.filter( (auto) => auto.title.includes(Chevrolet));
// const chevyAutos = autoData.filter( (auto) => auto.title.includes(Chevrolet));

this.setState({ autos: chevyAutos });
}

let filterJeep = () => {
const jeepAutos = autos.filter( (auto) => auto.title.includes(Jeep));
// const jeepAutos = autoData.filter( (auto) => auto.title.includes(Jeep));

this.setState({ autos: jeepAutos });
}
return (
<div className=container>
<Row className=mb-4>
<Col>
<Button event-key=reset-autos onClick={onResetArray}>All Cars</Button>
</Col>
<Col>
<Button event-key=ford-autos onClick={filterFord}>Filter Ford</Button>
</Col>
<Col>
<Button event-key=chevy-autos onClick={filterChevy}>Filter Chevy</Button>
</Col>
<Col>
<Button event-key=jeep-autos onClick={filterJeep}>Filter Jeep</Button>
</Col>
</Row>


<AutoList autos={ this.state.autos } />
</div>

);
}
}
export default GetAutos;


I expect a subsequent button click to filter the data set in state. Instead, the click filters the array created by the .filter() method. My code works with a local import of my JSON data, but not with the fetched JSON.


More From » reactjs

 Answers
9

When you set the state with the filtered result you are removing entries from the source. You should instead store the filtered result in a different key.



For instance something like this.



const jeepAutos = autos.filter( (auto) => auto.title.includes(Jeep))
this.setState({
filteredAutos: jeepAutos
})


Then when rendering you would use it like so



<AutoList autos={ this.state.filteredAutos } />


Remember that initially filteredAutos would be empty, so to view all you would need to check for filtered items before passing



<AutoList autos={ filteredAutos.length > 0 ? filteredAutos : autos } />


Simple example to play with


[#51825] Sunday, July 21, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
margaritakristinak

Total Points: 502
Total Questions: 127
Total Answers: 98

Location: England
Member since Mon, May 17, 2021
3 Years ago
;